dbf-encoding.diff

Cesar Martinez Izquierdo, 10/04/2016 06:06 PM

Download (51 KB)

View differences:

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/DBFFeatureWriter.java (copia de trabajo)
37 37
import org.gvsig.fmap.dal.feature.Feature;
38 38
import org.gvsig.fmap.dal.feature.FeatureType;
39 39
import org.gvsig.fmap.dal.feature.exception.AttributeFeatureTypeNotSuportedException;
40
import org.gvsig.fmap.dal.store.dbf.utils.DbaseCodepage;
40 41
import org.gvsig.fmap.dal.store.dbf.utils.DbaseFileHeader;
41 42
import org.gvsig.fmap.dal.store.dbf.utils.DbaseFileWriter;
42 43

  
......
55 56
	public void begin(DBFStoreParameters storeParameters,
56 57
			FeatureType featureType, long numRows) throws DataException {
57 58

  
58
		// TODO if is new set the langID
59
		String charset = storeParameters.getEffectiveEncodingName();	
60
		if (charset==null) {
61
			// set a safe encoding in case none has been defined
62
			charset = "UTF-8";
63
		}
59 64
		try {
60
			myHeader = DbaseFileHeader.createDbaseHeader(featureType);
65
			
66
			myHeader = DbaseFileHeader.createDbaseHeader(featureType, charset);
61 67
		} catch (AttributeFeatureTypeNotSuportedException e1) {
62 68
			throw new WriteException(this.name, e1);
63 69
		}
64 70

  
65 71
		dbfFile = storeParameters.getDBFFile();
72
		
73
		// .cpg will be redundant if LDID was already set, but we still
74
		// want to write it with the hopes of increasing the range of programs
75
		// that will correctly interpret the charset
76
		DbaseCodepage cpWriter = new DbaseCodepage(dbfFile);
77
		cpWriter.write(charset);
66 78

  
67 79
		dbfChannel = null;
68 80

  
......
74 86
		}
75 87
		try{
76 88
			this.dbfWriter = new DbaseFileWriter(myHeader, dbfChannel, true);
77

  
78

  
79
			this.dbfWriter.setCharset(Charset.forName("ISO-8859-1"));
80 89
			} catch (InitializeException e) {
81 90
				throw new WriteException(this.name, e);
82 91
			}
......
108 117
		File f = new File(path);
109 118

  
110 119
		if (!f.exists()) {
111
			//			System.out.println("Creando fichero " + f.getAbsolutePath());
112

  
113 120
			if (!f.createNewFile()) {
114 121
				System.err.print("Error al crear el fichero "
115 122
						+ f.getAbsolutePath());
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/DBFLibrary.java (copia de trabajo)
43 43
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
44 44
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
45 45
import org.gvsig.fmap.dal.store.dbf.utils.DbaseFile;
46
import org.gvsig.metadata.MetadataLocator;
47
import org.gvsig.metadata.MetadataManager;
46 48
import org.gvsig.metadata.exceptions.MetadataException;
47 49
import org.gvsig.tools.ToolsLocator;
48 50
import org.gvsig.tools.dynobject.DynObjectValueItem;
......
71 73
				DBFStoreParameters.class,
72 74
				"DBFParameters.xml"
73 75
		);
74
		updateEncodingDefinition();
76
		
75 77
		FileHelper.registerParametersDefinition(
76 78
				DBFNewStoreParameters.PARAMETERS_DEFINITION_NAME,
77 79
				DBFNewStoreParameters.class,
......
86 88
		} catch (MetadataException e) {
87 89
			exs.add(e);
88 90
		}
89

  
91
		updateEncodingDefinition();
92
		
90 93
        DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator
91 94
				.getDataManager();
92 95

  
......
114 117

  
115 118
	private static void updateEncodingDefinition() {
116 119
		DynStruct parametersDefinition = ToolsLocator.getPersistenceManager().getDefinition(DBFStoreParameters.PARAMETERS_DEFINITION_NAME);
117

  
118
		DynObjectValueItem[] values = parametersDefinition.getDynField("encoding").getAvailableValues();
119

  
120
		DynObjectValueItem[] values = parametersDefinition.getDynField("Encoding").getAvailableValues();
120 121
		Set<DynObjectValueItem> charsetSet = new LinkedHashSet<DynObjectValueItem>(160);
121

  
122 122
		charsetSet.addAll( Arrays.asList(values) );
123
		
124
		MetadataManager metadataManager = MetadataLocator.getMetadataManager();
125
		DynStruct dynStruct = metadataManager.getDefinition(DBFStoreProvider.METADATA_DEFINITION_NAME);
126
		DynObjectValueItem[] metadataValues = dynStruct.getDynField("Encoding").getAvailableValues();
127
		Set<DynObjectValueItem> metadataCharsetSets = new LinkedHashSet<DynObjectValueItem>(160);
128
		metadataCharsetSets.addAll( Arrays.asList(metadataValues) );
129
		
123 130
		Map<String,Charset> charsets = Charset.availableCharsets();
124 131
		Iterator<String> iter = charsets.keySet().iterator();
125 132
		while (iter.hasNext()){
126 133
			String value = (String) iter.next();
127 134
			String label= value;
128
			charsetSet.add(new DynObjectValueItem(value, label));
135
			DynObjectValueItem item = new DynObjectValueItem(value, label);
136
			charsetSet.add(item);
137
			metadataCharsetSets.add(item);
129 138
		}
130 139

  
131 140
		parametersDefinition.getDynField("Encoding")
132 141
			.setAvailableValues(
133 142
					(DynObjectValueItem[]) charsetSet.toArray(new DynObjectValueItem[charsets.size()])
134 143
			);
144
		dynStruct.getDynField("Encoding")
145
			.setAvailableValues(
146
					(DynObjectValueItem[]) metadataCharsetSets.toArray(
147
						new DynObjectValueItem[metadataCharsetSets.size()])
148
			);
135 149

  
136

  
137 150
	}
138 151
}
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/DBFStoreParameters.java (copia de trabajo)
29 29
import java.util.Locale;
30 30
import org.apache.commons.lang3.BooleanUtils;
31 31
import org.apache.commons.lang3.StringUtils;
32

  
32
import org.gvsig.fmap.dal.DataParameters;
33 33
import org.gvsig.fmap.dal.FileHelper;
34 34
import org.gvsig.fmap.dal.OpenDataStoreParameters;
35
import org.gvsig.fmap.dal.exception.CopyParametersException;
35 36
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
36 37
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
37 38
import org.gvsig.fmap.dal.spi.AbstractDataParameters;
38 39
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
40
import org.gvsig.fmap.dal.store.dbf.utils.DbaseCodepage;
39 41
import org.gvsig.tools.dynobject.DelegatedDynObject;
40 42
import org.slf4j.Logger;
41 43
import org.slf4j.LoggerFactory;
......
54 56
	public static final String DATE_FORMAT = "dateFormat";
55 57
	public static final String LOCALE = "locale";
56 58
    public static final String ALLOW_DUPLICATED_FIELD_NAMES = "allowDuplicatedFieldNames";
59
    // We don't want to persist or show effective encoding in the store parameters dialog
60
    // But we still need it to properly encode layers when editing!! 
61
    private String effectiveEncoding = null;
57 62

  
58 63
	private DelegatedDynObject parameters;
59 64

  
......
109 114
	public void setDBFFile(File file) {
110 115
		this.setDynValue(DBFFILE_PARAMTER_NAME, file);
111 116
	}
117
	
118
	public String getCPGFileName() {
119
		return DbaseCodepage.getCpgFileName(getDBFFileName());
120
	}
121
	
122
	public File getCPGFile() {
123
		return new File(DbaseCodepage.getCpgFileName(getDBFFileName()));
124
	}
112 125

  
126

  
113 127
	public void setDBFFile(String fileName) {
114 128
		this.setDynValue(DBFFILE_PARAMTER_NAME, fileName);
115 129
	}
......
132 146
                }
133 147
		return Charset.forName(name);
134 148
	}
149
	/**
150
	 * The encoding actually used to read/write the dbf
151
	 * 
152
	 * @param encoding
153
	 */
154
	public String getEffectiveEncodingName() {
155
		if (effectiveEncoding==null) {
156
			return getEncodingName();
157
		}
158
		return effectiveEncoding.trim();
159
	}
160
	
161
	/**
162
	 * The encoding actually used to read/write the dbf
163
	 * 
164
	 * @param encoding
165
	 */
166
	public Charset getEffectiveEncoding() {
167
		String name = getEffectiveEncodingName();
168
		if (name==null) {
169
			return null;
170
		}
171
		return Charset.forName(name);
172
	}
135 173

  
136 174
	public void setEncoding(String encoding) {
137 175
		this.setEncoding(Charset.forName(encoding));
138 176
    }
177
	
178
	/**
179
	 * The encoding actually used to read/write the dbf
180
	 * 
181
	 * @param encoding
182
	 */
183
	public void setEffectiveEncoding(String encoding) {
184
		this.effectiveEncoding = encoding;
185
    }
139 186

  
140 187
    public boolean handleDatesAsStrings() {
141 188
        Boolean x = (Boolean) getDynValue(HANDLE_DATES_AS_STRINGS);
......
150 197
    public void setEncoding(Charset charset) {
151 198
        this.setDynValue(ENCODING_PARAMTER_NAME, charset.name());
152 199
	}
200
    
201
	/**
202
	 * The encoding actually used to read/write the dbf
203
	 * 
204
	 * @param encoding
205
	 */
206
    public void setEffectiveEncoding(Charset charset) {
207
    	this.effectiveEncoding = charset.name();
208
	}
209
    
210
    @Override
211
    public DataParameters getCopy() {
212
    	DataParameters copy = super.getCopy();
213
    	if (copy instanceof DBFStoreParameters) {
214
    		DBFStoreParameters dbfParams = (DBFStoreParameters) copy;
215
    		dbfParams.setEffectiveEncoding(this.effectiveEncoding);
216
    	}
217
    	return copy;
218
    }
153 219

  
154 220
	protected DelegatedDynObject getDelegatedDynObject() {
155 221
		return parameters;
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 (copia de trabajo)
179 179
        if (METADATA_ENCODING.equalsIgnoreCase(name)) {
180 180
            return this.dbfFile.getOriginalCharset();
181 181
        } else if (METADATA_CODEPAGE.equalsIgnoreCase(name)) {
182
            return new Byte(this.dbfFile.getCodePage());
182
            return new Integer(this.dbfFile.getCodePageInt());
183 183
        }
184 184
        return super.getDynValue(name);
185 185
    }
......
690 690
    protected void openFile() throws FileNotFoundException,
691 691
            UnsupportedVersionException, IOException, DataException {
692 692
        this.dbfFile.open();
693
        // necessary when editing the file
694
        this.getDBFParameters().setEffectiveEncoding(this.dbfFile.getCharsetName());
693 695
    }
694 696

  
695 697
    public void close() throws CloseException {
......
930 932
    public ResourceProvider getResource() {
931 933
        return dbfResource;
932 934
    }
935

  
933 936
}
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/utils/DbaseFile.java (copia de trabajo)
206 206
    }
207 207

  
208 208
    public DbaseFile(File afile, Charset chars) {
209
        this(afile, null, false);
209
        this(afile, chars, false);
210 210
    }
211 211

  
212 212
    public DbaseFile(File afile, Charset chars, boolean allowDuplicatedFieldNames) {
......
215 215
        this.allowDuplicatedFieldNames = allowDuplicatedFieldNames;
216 216
    }
217 217

  
218
    /**
219
     * @deprecated Use {@link #getCodePageInt()} instead
220
     */
221
    @Deprecated
218 222
	public byte getCodePage() {
223
		return (byte) myHeader.getLanguageID();
224
	}
225
	
226
	public int getCodePageInt() {
219 227
		return myHeader.getLanguageID();
220 228
	}
229
	
230
	/**
231
	 * Returns the charset used to read/write this dbf. Maybe different
232
	 * from the declared in the file if we have forced a different one
233
	 * 
234
	 * @return
235
	 */
236
	public String getCharsetName() { 
237
		return chars.name();
238
		//return myHeader.getCharsetName();
239
	}
221 240

  
241
	/**
242
	 * Returns the charset declared on the dbf file (or the
243
	 * default one if none is declared)
244
	 * 
245
	 * @return
246
	 */
247
	public String getOriginalCharsetName() {
248
		return myHeader.getOriginalCharset();
249
	}
250

  
222 251
	// Retrieve number of records in the DbaseFile
223 252
	public int getRecordCount() {
224 253
		return myHeader.getNumRecords();
......
295 324
		cachedRecord.position(fieldOffset);
296 325
		cachedRecord.get(data);
297 326

  
298
		try {
299
			return new String(data, chars.name());
300
		} catch (java.io.UnsupportedEncodingException e) {
301
			throw new UnsupportedEncodingException(
302
					e);
303
		}
304

  
327
		return new String(data, chars);
305 328
	}
306 329

  
307 330
	public void setFieldValue(int rowIndex, int fieldId, Object obj) throws UnsupportedEncodingException, WriteException {
......
313 336
					+ myHeader.getHeaderLength() + 1;
314 337

  
315 338
			ByteBuffer aux = ByteBuffer.wrap(data);
316
			aux.put(str.getBytes(chars.name()));
339
			aux.put(str.getBytes(chars));
317 340
//			raf.seek(recordOffset + fieldOffset);
318 341
//			raf.writeBytes(str);
319 342
			aux.flip();
......
414 437
	 */
415 438
	public void open() throws FileNotFoundException,
416 439
			UnsupportedVersionException, IOException {
417
		/*
418
		 * 01h DOS USA code page 437 02h DOS Multilingual code page 850 03h
419
		 * Windows ANSI code page 1252 04h Standard Macintosh 64h EE MS-DOS code
420
		 * page 852 65h Nordic MS-DOS code page 865 66h Russian MS-DOS code page
421
		 * 866 67h Icelandic MS-DOS 68h Kamenicky (Czech) MS-DOS 69h Mazovia
422
		 * (Polish) MS-DOS 6Ah Greek MS-DOS (437G) 6Bh Turkish MS-DOS 96h
423
		 * Russian Macintosh 97h Eastern European Macintosh 98h Greek Macintosh
424
		 * C8h Windows EE code page 1250 C9h Russian Windows CAh Turkish Windows
425
		 * CBh Greek Windows
426
		 */
440

  
427 441
		if (!file.exists()) {
428 442
			throw new FileNotFoundException(file);
429 443
		}
......
452 466
		} else {
453 467
			myHeader.readHeader(buffer, chars.name(), allowDuplicatedFieldNames);
454 468
		}
455
		charsOriginal = Charset.forName(myHeader.mappingEncoding(myHeader.getCharsetName()));
469
		if (myHeader.getLanguageID()==0x00) {
470
			// read from the .cpg file if ldid is 0x00
471
			DbaseCodepage cpReader = new DbaseCodepage(file);
472
			String charsetName = cpReader.read();
473
			if (charsetName == null) {
474
				charsetName = "ISO-8859-1"; // for compatibility with old gvSIG files
475
			}
476
			charsOriginal = Charset.forName(myHeader.mappingEncoding(charsetName));
477
		}
478
		else {
479
			charsOriginal = Charset.forName(myHeader.mappingEncoding(myHeader.getOriginalCharset()));			
480
		}
456 481
		if (chars == null) {
457 482
			chars = charsOriginal;
458 483
		}
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/utils/DbaseFileHeader.java (copia de trabajo)
85 85
    // collection of header records.
86 86
    private DbaseFieldDescriptor[] myFieldDescriptions;
87 87

  
88
	private byte myLanguageID;
88
	private int myLanguageID = 0x00;
89
	/**
90
	 * Only considered when myLanguageID = 0x00; 
91
	 */
92
	private String charset = null;
89 93

  
90 94
	private List<String>   encodingSupportedByString = null;
91 95

  
96
	private int origLanguageID = 0x00;
97
	
98
	/**
99
	 * Headers must always be encoded using ASCII/ISO-8859-1, regardless the
100
	 * encoding of the records
101
	 */
102
	private static final Charset headerCharset = Charset.forName("ISO-8859-1");
103

  
92 104
    /**
93 105
     * DbaseFileHreader constructor comment.
94 106
     */
......
431 443

  
432 444
        in.order(ByteOrder.BIG_ENDIAN);
433 445

  
434
        // skip the reserved bytes in the header.
435
        // in.position(in.position() + 20);
436

  
437
        // Leemos el byte de language
446
        // read the language bit (LDID) 
438 447
        in.position(29);
439
        myLanguageID = in.get();
440
        if (charsName == null) {
448
    	origLanguageID  = byteAsUnsigned(in.get());
449
        if (charsName != null) {
450
        	// ignore the language bit, use the provided charset name
451
        	myLanguageID = DbaseCodepage.getLdid(charsName);
452
        	this.charset = charsName;
453
		}
454
        else {
455
            // use the read the language bit
456
        	myLanguageID = origLanguageID;
441 457
        	charsName = getCharsetName();
442
        	charsName = mappingEncoding(charsName);
443
		}
458
        }
444 459

  
445

  
446 460
        // Posicionamos para empezar a leer los campos.
447 461
        in.position(32);
448 462

  
......
455 469

  
456 470
        List fieldNames = new ArrayList<String>();
457 471

  
472
        // FIXME: should field names be always read using ISO8859-1??
458 473
        for (int i = 0; i < myNumFields; i++) {
459 474
            myFieldDescriptions[i] = new DbaseFieldDescriptor();
460 475

  
......
462 477
            byte[] buffer = new byte[11];
463 478
            in.get(buffer);
464 479
            String fieldName;
465
            if (charsName != null) {
466
                fieldName = new String(buffer,
467
						charsName);
468
			} else {
469
			    fieldName = new String(buffer);
470
			}
480
            fieldName = new String(buffer, headerCharset);
471 481

  
472 482
            if(allowDuplicatedFieldNames){
473 483
                fieldName = getUniqueFieldName(fieldName, fieldNames);
......
520 530
    public void setNumRecords(int inNumRecords) {
521 531
        myNumRecords = inNumRecords;
522 532
    }
523

  
524
    /*
525
     * Write the header data to the DBF file.
526
     *
527
     * @param out DOCUMENT ME!
528
     *
529
     * @throws Exception DOCUMENT ME!
530
     *
531
           public void writeHeader(LEDataOutputStream out) throws Exception {
532
               // write the output file type.
533
               out.writeByte(myFileType);
534
               // write the date stuff
535
               Calendar c = Calendar.getInstance();
536
               c.setTime(new Date());
537
               out.writeByte(c.get(Calendar.YEAR) - 1900);
538
               out.writeByte(c.get(Calendar.MONTH) + 1);
539
               out.writeByte(c.get(Calendar.DAY_OF_MONTH));
540
               // write the number of records in the datafile.
541
               out.writeInt(myNumRecords);
542
               // write the length of the header structure.
543
               out.writeShort(myHeaderLength);
544
               // write the length of a record
545
               out.writeShort(myRecordLength);
546
               // write the reserved bytes in the header
547
               for (int i = 0; i < 20; i++)
548
                   out.writeByte(0);
549
               // write all of the header records
550
               int tempOffset = 0;
551
               for (int i = 0; i < myFieldDescriptions.length; i++) {
552
                   // write the field name
553
                   for (int j = 0; j < 11; j++) {
554
                       if (myFieldDescriptions[i].myFieldName.length() > j) {
555
                           out.writeByte((int) myFieldDescriptions[i].myFieldName.charAt(
556
                                   j));
557
                       } else {
558
                           out.writeByte(0);
559
                       }
560
                   }
561
                   // write the field type
562
                   out.writeByte(myFieldDescriptions[i].myFieldType);
563
                   // write the field data address, offset from the start of the record.
564
                   out.writeInt(tempOffset);
565
                   tempOffset += myFieldDescriptions[i].myFieldLength;
566
                   // write the length of the field.
567
                   out.writeByte(myFieldDescriptions[i].myFieldLength);
568
                   // write the decimal count.
569
                   out.writeByte(myFieldDescriptions[i].myDecimalCount);
570
                   // write the reserved bytes.
571
                   for (int j = 0; j < 14; j++)
572
                       out.writeByte(0);
573
               }
574
               // write the end of the field definitions marker
575
               out.writeByte(0x0D);
576
           }
533
    
534
    /**
535
     * Returns the value of the unsigned byte as a short
536
     * Bytes are always signed in Java, so if we are reading a C unsigned byte
537
     * with value > 128, it will appear as a negative value.
538
     * 
539
     * In this case, we need to get the original unsigned value and return it as
540
     * short or int, as byte will never correctly store the value in Java. 
541
     * 
542
     * @return
577 543
     */
544
    private int byteAsUnsigned(byte b) {
545
    	int i;
546
    	if (b<0) {
547
    		i = b & 0xFF;
548
    	}
549
    	else {
550
    		i = b;
551
    	}
552
    	return i;
553
    }
578 554

  
579 555
    /**
580 556
     * Class for holding the information assicated with a record.
......
598 574
        int myDecimalCount;
599 575
    }
600 576

  
601
	public byte getLanguageID() {
577
	/**
578
	 * Gets the Language driver IDs (code page) defined on the file header (or guessed
579
	 * from the provided charset)
580
	 * 
581
	 * Some examples:
582
	 * 	01h		DOS USA	code page 437
583
		02h		DOS Multilingual code page 850
584
		03h		Windows ANSI code page 1252
585
		04h		Standard Macintosh
586
		64h		EE MS-DOS code page 852
587
		65h		Nordic MS-DOS code page 865
588
		66h		Russian MS-DOS code page 866
589
		67h		Icelandic MS-DOS
590
		68h		Kamenicky (Czech) MS-DOS
591
		69h		Mazovia (Polish) MS-DOS
592
		6Ah		Greek MS-DOS (437G)
593
		6Bh		Turkish MS-DOS
594
		96h		Russian Macintosh
595
		97h		Eastern European Macintosh
596
		98h		Greek Macintosh
597
		C8h		Windows EE	code page 1250
598
		C9h		Russian Windows
599
		CAh		Turkish Windows
600
		CBh		Greek Windows
601
		
602
		See the java equivalences in {@link DbaseCodepage#dbfLdid} & {@link DbaseCodepage#ldidJava} objects.
603
		 
604
		See some others here: https://github.com/infused/dbf/blob/master/docs/supported_encodings.csv
605
	 * @return
606
	 */
607
	public int getLanguageID() {
608
		
602 609
		return myLanguageID;
603 610
	}
604 611

  
......
606 613

  
607 614
	public static DbaseFileHeader createDbaseHeader(FeatureType featureType)
608 615
			throws AttributeFeatureTypeNotSuportedException {
616
		return createDbaseHeader(featureType, null);
617
	}
618
	
619
	public static DbaseFileHeader createDbaseHeader(FeatureType featureType, String charsetName)
620
			throws AttributeFeatureTypeNotSuportedException {
609 621
		DbaseFileHeader header = new DbaseFileHeader();
610 622
		Iterator iterator=featureType.iterator();
611
		// TODO header.myLanguageID = langId;
623
		header.myLanguageID = DbaseCodepage.getLdid(charsetName);
624
		header.charset = charsetName;
612 625
		while (iterator.hasNext()) {
613 626
			FeatureAttributeDescriptor descriptor = (FeatureAttributeDescriptor) iterator.next();
614 627

  
......
643 656
		}
644 657
		return header;
645 658
	}
659
	
646 660
	/**
647 661
	 * Write the header data to the DBF file.
648 662
	 *
......
685 699
		// write the length of a record
686 700
		buffer.putShort((short) myRecordLength);
687 701

  
688
		// // write the reserved bytes in the header
689
		// for (int i=0; i<20; i++) out.writeByteLE(0);
690
		buffer.position(buffer.position() + 20);
702
		// write the reserved bytes in the header
703
		buffer.position(buffer.position() + 17);
704
		
705
		// write the language id
706
		buffer.put((byte)getLanguageID());
707
		
708
		// write the reserved bytes in the header		
709
		buffer.position(buffer.position() + 2);
691 710

  
692 711
		// write all of the header records
693 712
		int tempOffset = 0;
......
734 753
		}
735 754
	}
736 755

  
737
	/**
738
	 * 	01h		DOS USA	code page 437
739
		02h		DOS Multilingual code page 850
740
		03h		Windows ANSI code page 1252
741
		04h		Standard Macintosh
742
		64h		EE MS-DOS code page 852
743
		65h		Nordic MS-DOS code page 865
744
		66h		Russian MS-DOS code page 866
745
		67h		Icelandic MS-DOS
746
		68h		Kamenicky (Czech) MS-DOS
747
		69h		Mazovia (Polish) MS-DOS
748
		6Ah		Greek MS-DOS (437G)
749
		6Bh		Turkish MS-DOS
750
		96h		Russian Macintosh
751
		97h		Eastern European Macintosh
752
		98h		Greek Macintosh
753
		C8h		Windows EE	code page 1250
754
		C9h		Russian Windows
755
		CAh		Turkish Windows
756
		CBh		Greek Windows
757
	 * @return
758
	 */
759 756
	public String getCharsetName() {
760
		switch (getLanguageID()) {
761
		case 0x01:
762
			return "US-ASCII";
763
		case 0x02:
764
			return "ISO-8859-1";
765
		case 0x03:
766
			return "windows-1252";
767
		case 0x04:
768
			return "mac";
769
		case 0x64:
770
			return "ISO-8859-1";
771
		case 0x65:
772
			return "ISO-8859-1";
773
		case 0x66:
774
			return "ISO-8859-1";
775
		case 0x67:
776
			return "ISO-8859-1";
777
		case 0x68:
778
			return "greek";
779
		case 0x69:
780
			return "ISO-8859-1";
781
		case 0x6A:
782
			return "greek";
783
		case 0x6B:
784
			return "ISO-8859-1";
785

  
786
		default:
787
			return "ISO-8859-1";
757
		return getCharsetName(getLanguageID());
758
	}
759
	
760
	public String getCharsetName(int ldid) {
761
		if (ldid!=0) {
762
			// prefer the charset defined by the ldid
763
			for (int i=0; i<DbaseCodepage.dbfLdid.length; i++) {
764
				if (DbaseCodepage.dbfLdid[i]==ldid) {
765
					return DbaseCodepage.ldidJava[i];
766
				}
767
			}
788 768
		}
769
		if (charset!=null) {
770
			// use charset otherwise
771
			return charset;
772
		}
773
		// default
774
		return "ISO-8859-1";
789 775
	}
776
	
777
	public String getOriginalCharset() {
778
		return getCharsetName(this.origLanguageID);
779
	}
790 780

  
791 781
	public String mappingEncoding(String dbfEnconding) {
792 782
		if(encodingSupportedByString.contains(dbfEnconding))
......
809 799
        }
810 800
        return tempFieldName;
811 801
    }
802

  
812 803
}
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/utils/DbaseFileWriter.java (copia de trabajo)
24 24
package org.gvsig.fmap.dal.store.dbf.utils;
25 25

  
26 26
import java.io.IOException;
27
import java.nio.BufferOverflowException;
27 28
import java.nio.ByteBuffer;
28 29
import java.nio.MappedByteBuffer;
29 30
import java.nio.channels.FileChannel;
30 31
import java.nio.charset.Charset;
31 32
import java.text.FieldPosition;
32 33
import java.text.NumberFormat;
34
import java.util.Arrays;
33 35
import java.util.Calendar;
34 36
import java.util.Date;
35 37
import java.util.Iterator;
......
66 68
        new DbaseFileWriter.FieldFormatter();
67 69
    FileChannel channel;
68 70
    private ByteBuffer buffer;
69
    // private final Number NULL_NUMBER = new Integer(0);
70
    private final String NULL_STRING = "";
71
    private final String NULL_DATE = "        ";
72 71
    private boolean headDrity = false;
72
    private ByteBuffer blank;
73
    private int blankSize;
74
    
75
    //private Charset charset = Charset.forName("ISO-8859-1");
76
    private Charset charset;
73 77

  
74
    // TODO: READ HEADER AND STABLIST THE RIGHT CHARSET
75
    private Charset charset = Charset.forName("ISO-8859-1");
76

  
77 78
    /**
78 79
     * Create a DbaseFileWriter using the specified header and writing to the
79 80
     * given channel.
......
93 94
        this.header = header;
94 95
        this.channel = out;
95 96
        this.headDrity = isNew;
96

  
97
        this.setCharset(Charset.forName(header.mappingEncoding(header.getCharsetName())));
98
        
97 99
        init();
98 100
    }
99 101

  
......
175 177
                if (type == DataTypes.GEOMETRY) {
176 178
                    continue;
177 179
                }
178
                String fieldString = fieldString(fad, feature);
179
                if (fieldString == null) {
180
                    if (type == DataTypes.STRING) {
181
                        fieldString = NULL_STRING;
182
                    } else
183
                        if (type == DataTypes.DATE) {
184
                            fieldString = NULL_DATE;
185
                        } else {
186
                            fieldString = "0";
187
                        }
188
                }
189
                try {
190
                    buffer.put(fieldString.getBytes(charset.name()));
191
                } catch (java.io.UnsupportedEncodingException e) {
192
                    throw new UnsupportedEncodingException(e);
193
                }
180
                encodeField(fad, feature);
194 181
            }
195 182
        } catch (Exception e) {
196 183
            throw new WriteException("DbaseFileWriter", e);
197 184
        }
198 185
    }
199

  
186
    
200 187
    private void moveToEOF() throws IOException {
201 188
        this.moveTo(this.header.getNumRecords());
202 189
    }
......
235 222
        write();
236 223
    }
237 224

  
238
    private String fieldString(FeatureAttributeDescriptor attr, Feature feature) {
225
    private String fieldString(FeatureAttributeDescriptor attr, Feature feature) throws java.io.UnsupportedEncodingException {
239 226
        int type = attr.getType();
240 227
        int dbfFieldIndex = this.header.getFieldIndex(attr.getName());
241 228
        final int fieldLen = header.getFieldLength(dbfFieldIndex);
......
288 275
                                    if (DataTypes.STRING == type) {
289 276
                                        String s =
290 277
                                            feature.getString(attr.getIndex());
291
                                        fieldString =
292
                                            formatter.getFieldString(fieldLen,
293
                                                s);
278
                                        return s;
294 279
                                    }
295 280
        return fieldString;
296 281

  
297 282
    }
298 283

  
299
    // private String fieldString(Object obj,final int col) {
300
    // String o;
301
    // final int fieldLen = header.getFieldLength(col);
302
    // switch (header.getFieldType(col)) {
303
    // case 'C':
304
    // case 'c':
305
    // o = formatter.getFieldString(
306
    // fieldLen,
307
    // (obj instanceof NullValue)? NULL_STRING : ((StringValue) obj).getValue()
308
    // );
309
    // break;
310
    // case 'L':
311
    // case 'l':
312
    // o = (obj instanceof NullValue) ? "F" : ((BooleanValue)obj).getValue() ==
313
    // true ? "T" : "F";
314
    // break;
315
    // case 'M':
316
    // case 'G':
317
    // o = formatter.getFieldString(
318
    // fieldLen,
319
    // (obj instanceof NullValue) ? NULL_STRING : ((StringValue) obj).getValue()
320
    // );
321
    // break;
322
    // /* case 'N':
323
    // case 'n':
324
    // // int?
325
    // if (header.getFieldDecimalCount(col) == 0) {
326
    //
327
    // o = formatter.getFieldString(
328
    // fieldLen, 0, (Number) (obj == null ? NULL_NUMBER :
329
    // Double.valueOf(obj.toString()))
330
    // );
331
    // break;
332
    //
333
    // }
334
    // */
335
    // case 'N':
336
    // case 'n':
337
    // case 'F':
338
    // case 'f':
339
    // Number number = null;
340
    // if(obj instanceof NullValue){
341
    // number = NULL_NUMBER;
342
    // }else{
343
    // NumericValue gVal = (NumericValue) obj;
344
    // number = new Double(gVal.doubleValue());
345
    // }
346
    // o = formatter.getFieldString(fieldLen,
347
    // header.getFieldDecimalCount(col),
348
    // number);
349
    // break;
350
    // case 'D':
351
    // case 'd':
352
    // if (obj instanceof NullValue)
353
    // o = NULL_DATE;
354
    // else
355
    // o = formatter.getFieldString(((DateValue)obj).getValue());
356
    // break;
357
    // default:
358
    // throw new RuntimeException("Unknown type " + header.getFieldType(col));
359
    // }
360
    //
361
    // return o;
362
    // }
284
    private void encodeField(FeatureAttributeDescriptor attr, Feature feature) throws java.io.UnsupportedEncodingException, UnsupportedEncodingException {
285
        int type = attr.getType();
286
        int dbfFieldIndex = this.header.getFieldIndex(attr.getName());
287
        final int fieldLen = header.getFieldLength(dbfFieldIndex);
288
        String fieldString = "";
289
        if (DataTypes.BOOLEAN == type) {
290
            boolean b = feature.getBoolean(attr.getIndex());
291
            if (b) {
292
            	safeEncode("T", 1, true); 
293
            } else {
294
            	safeEncode("F", 1, true);
295
            }
296
        } else
297
            if (DataTypes.BYTE == type) {
298
                fieldString = String.valueOf(feature.getByte(attr.getIndex()));
299
                safeEncode(fieldString, 8, false);
300
            } else
301
                if (DataTypes.DATE == type) {
302
                    Date date = feature.getDate(attr.getIndex());
303
                    fieldString = formatter.getFieldString(date);
304
                    safeEncode(fieldString, 8, false);
305
                } else
306
                    if (DataTypes.DOUBLE == type) {
307
                        double d = feature.getDouble(attr.getIndex());
308
                        fieldString =
309
                            formatter.getFieldString(fieldLen,
310
                                header.getFieldDecimalCount(dbfFieldIndex), d);
311
                        safeEncode(fieldString, fieldLen, false);
312
                    } else
313
                        if (DataTypes.FLOAT == type) {
314
                            float f = feature.getFloat(attr.getIndex());
315
                            fieldString =
316
                                formatter.getFieldString(fieldLen,
317
                                    header.getFieldDecimalCount(dbfFieldIndex),
318
                                    f);
319
                            safeEncode(fieldString, fieldLen, false);
320
                        } else
321
                            if (DataTypes.INT == type) {
322
                                int integer = feature.getInt(attr.getIndex());
323
                                fieldString =
324
                                    formatter.getFieldString(fieldLen, header
325
                                        .getFieldDecimalCount(dbfFieldIndex),
326
                                        integer);
327
                                safeEncode(fieldString, fieldLen, false);
328
                            } else
329
                                if (DataTypes.LONG == type) {
330
                                    long l = feature.getLong(attr.getIndex());
331
                                    fieldString =
332
                                        formatter
333
                                            .getFieldString(
334
                                                fieldLen,
335
                                                header
336
                                                    .getFieldDecimalCount(dbfFieldIndex),
337
                                                l);
338
                                    safeEncode(fieldString, fieldLen, false);
339
                                } else
340
                                    if (DataTypes.STRING == type) {
341
                                        String s =
342
                                            feature.getString(attr.getIndex());
343
//                                        System.out.println(fieldLen);
344
                                        safeEncode(s, fieldLen, true);
345
                                    }
363 346

  
347
    }
348

  
364 349
    /**
350
     * Returns a safely padded (and potentially truncated) string 
351
     * 
352
     * This may truncate some record, but it is required to ensure
353
     * that the field limit is not overflowed when using 
354
     * variable-length charsets such as UTF-8.
355
     * @throws UnsupportedEncodingException 
356
     */
357
    private void safeEncode(String in, int limit, boolean rightPadding) throws UnsupportedEncodingException {
358
    	try {
359
    		byte[] encodedString = in.getBytes(this.charset);
360
    		if (encodedString.length>limit) {
361
    			// too long, truncating
362
    			/*
363
    			 * The block code bellow is equivalent to this simple code
364
    			 * fragment:
365

  
366
    		if (rightPadding) {
367
    			in = in.substring(0, in.length()-1);
368
    			encodedString = in.getBytes(charset);
369
    		}
370
    		else {
371
    			in.substring(1, in.length());
372
    			encodedString = in.getBytes(charset);
373
    		}
374

  
375
    		However, the implemented algorithm has a much better performance
376
    		for the average and worst cases (when the input string has a lot
377
    		of multibyte characters), while keeping a good performance
378
    		for the best case (when all the characters in the input string
379
    		can be represented as single bytes using the selected charset).
380

  
381
    		The general strategy is to compute the deviation from the
382
    		required maximum number of bytes (limit) and the actual number
383
    		of bytes of the encoded String.
384

  
385
    		Then, we use this deviation to estimate the amount of characters
386
    		to truncate, based on the average factor of bytes per char in the
387
    		input string.
388

  
389
    		We truncate the string using this approach until the deviation
390
    		gets stable.
391

  
392
    		Finally, as we should be close enough to the right truncation position,
393
    		we increment/decrement the truncated string by only 1 character, to
394
    		ensure we truncate in the exact position. 
395
    			 */
396
    			String str = in;
397
    			int estimatedDiff, deviation;
398
    			int deviationPrev;
399
    			double ratio;
400
    			byte[] encodedChar;
401
    			int truncatePos = 0;
402
    			deviation = encodedString.length - limit;
403
    			deviationPrev = deviation - 1;
404
    			while(Math.abs(deviation)>Math.abs(deviationPrev) && str.length()>0) {
405
    				ratio = ((double)encodedString.length) / ((double)str.length());
406
    				// apply the estimated diff, ensuring it is at least >= 1.0 in absolute value
407
    				estimatedDiff = Math.max((int)(((double)deviation)/ratio), (int)(Math.signum(deviation)*1));
408
    				// too long, truncating
409
    				if (rightPadding) {
410
    					truncatePos = Math.max(str.length()-estimatedDiff, 0);
411
    					str = in.substring(0, truncatePos);
412
    				}
413
    				else {
414
    					truncatePos = Math.max(truncatePos + estimatedDiff, 0);
415
    					str = in.substring(truncatePos);				  
416
    				}
417
    				encodedString = str.getBytes(charset);
418
    				deviationPrev = deviation;
419
    				deviation = encodedString.length - limit;
420
    			}
421
    			// now we are close enough, get the exact position for truncating
422
    			while (encodedString.length>limit) {
423
    				// too long, truncating
424
    				//    				  System.out.println("truncating");
425
    				if (rightPadding) {
426
    					str = in.substring(0, str.length()-1);
427
    				}
428
    				else {
429
    					truncatePos = truncatePos + 1;
430
    					str = in.substring(truncatePos);
431
    				}
432
    				encodedString = str.getBytes(charset);
433
    			}
434
    			while (encodedString.length<limit && str.length()<in.length()) {
435
    				// Extend if necessary:
436
    				// 1 - Get the length in bytes of the next char
437
    				// 2 - Add the char to the substring if we are still within the limits 
438
    				//    				  System.out.println("extending");
439
    				if (rightPadding) {
440
    					encodedChar = in.substring(str.length(), str.length()+1).getBytes(charset);
441
    				}
442
    				else {
443
    					encodedChar = in.substring(truncatePos-1, truncatePos).getBytes(charset);
444
    					//    					  System.out.println(encodedChar);
445
    					//    					  System.out.println(encodedChar.length);
446
    					//    					  System.out.println(testStrings[i].substring(truncatePos-1, truncatePos));
447
    				}
448
    				//    				  System.out.println(testStrings[i].substring(in.length(), in.length()+1));
449
    				if ((encodedString.length + encodedChar.length)>limit) {
450
    					// one more char would overflow the limit
451
    					break;
452
    				}
453
    				// too short, extending
454
    				if (rightPadding) {
455
    					str = in.substring(0, str.length()+1);
456
    				}
457
    				else {
458
    					truncatePos = truncatePos - 1;
459
    					str = in.substring(truncatePos);
460
    				}
461
    				encodedString = str.getBytes(charset);
462
    			}
463
    		}
464
    		if (rightPadding) {
465
    			buffer.put(encodedString);
466
    		}
467
    		if (encodedString.length<limit) {
468
    			// too short, padding
469
    			int i = encodedString.length;
470
    			while (i<limit) {
471
    				blank.position(0);
472
    				buffer.put(blank);
473
    				i=i+blankSize;
474
    			}
475
    			if (i>limit) {
476
    				// Might happen for instance if charset is UTF16 and the
477
    				// limit of characters in the field is an odd number
478
    				throw new UnsupportedEncodingException(new Exception("Impossible to encode this DBF using the selected charset"));
479
    			}
480
    		}
481
    		if (!rightPadding) {
482
    			buffer.put(encodedString);
483
    		}
484
    	}
485
		catch(BufferOverflowException exc) {
486
			// Might happen for instance if charset is UTF16 and the
487
			// limit of characters in the field is an odd number
488
			throw new UnsupportedEncodingException(exc);
489
		}
490
    }
491
    
492
    /**
493
     * Returns a safely padded (and potentially truncated) string 
494
     * 
495
     * This may truncate some record, but it is required to ensure
496
     * that the field limit is not overflowed when using 
497
     * variable-length charsets such as UTF-8.
498
     * 
499
     * This implementation is not used but it is kept here for reference.
500
     * It is fully equivalent to the {@link #safeEncode(String, int, boolean)}
501
     * method and easier to understand, but this implementation is much
502
     * slower for any multibyte charset (such as UTF-8).
503
     *  
504
     * @throws UnsupportedEncodingException 
505
     */
506
    private void safeEncodeSlow(String in, int limit, boolean rightPadding) throws UnsupportedEncodingException {
507
    	try {
508
    		byte[] encodedString = in.getBytes(this.charset);
509
    		while (encodedString.length>limit) {
510
    			// too long, truncating
511
    			if (rightPadding) {
512
    				in = in.substring(0, in.length()-1);
513
    				encodedString = in.getBytes(charset);
514
    			}
515
    			else {
516
    				in.substring(1, in.length());
517
    				encodedString = in.getBytes(charset);
518
    			}
519
    		}
520
    		if (rightPadding) {
521
    			buffer.put(encodedString);
522
    		}
523
    		if (encodedString.length<limit) {
524
    			// too short, padding
525
    			int i = encodedString.length;
526
    			while (i<limit) {
527
    				blank.position(0);
528
    				buffer.put(blank);
529
    				i=i+blankSize;
530
    			}
531
    			if (i>limit) {
532
    				throw new UnsupportedEncodingException(new Exception("Impossible to encode this DBF using the selected charset"));
533
    			}
534
    		}
535
    		if (!rightPadding) {
536
    			buffer.put(encodedString);
537
    		}
538
    	}
539
    	catch(BufferOverflowException exc) {
540
    		// Might happen for instance if charset is UTF16 and the
541
    		// limit of characters in the field is an odd number
542
    		throw new UnsupportedEncodingException(exc);
543
    	}
544
    }
545

  
546

  
547
    /**
365 548
     * Release resources associated with this writer. <B>Highly recommended</B>
366 549
     * 
367 550
     * @throws CloseException
......
485 668
        public String getFieldString(int size, int decimalPlaces, double n) {
486 669
            buffer.delete(0, buffer.length());
487 670

  
488
            // if (n != null) {
489 671
            numFormat.setMaximumFractionDigits(decimalPlaces);
490 672
            numFormat.setMinimumFractionDigits(decimalPlaces);
491 673
            numFormat.format(n, buffer, new FieldPosition(
492 674
                NumberFormat.INTEGER_FIELD));
493
            // }
494

  
495
            int diff = size - buffer.length();
496
            if (diff >= 0) {
497
                while (diff-- > 0) {
498
                    buffer.insert(0, ' ');
499
                }
500
            } else {
501
                buffer.setLength(size);
502
            }
503 675
            return buffer.toString();
504 676
        }
505 677
    }
506 678

  
507 679
    public void setCharset(Charset charset) {
508 680
        this.charset = charset;
509

  
681
    	blank = charset.encode(" ");
682
    	blankSize = blank.limit();
510 683
    }
511 684

  
512 685
}
org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.file/org.gvsig.fmap.dal.file.shp/src/main/java/org/gvsig/fmap/dal/store/shp/SHPStoreProvider.java (copia de trabajo)
502 502
                                + "' file to replace with the new shx.\nThe new shx is in temporary file '" + str_base
503 503
                                + "'");
504 504
                        }
505
                        if (shpParams.getCPGFile().exists() && !shpParams.getCPGFile().delete()) {
506
                            logger.debug("Can't delete cpg file '" + shpParams.getCPGFile() + "'.");
507
                            throw new IOException("Can't delete cpg '"
508
                                + FilenameUtils.getBaseName(shpParams.getCPGFileName())
509
                                + "' file to replace with the new cpg.\nThe new cpg is in temporary file '" + str_base
510
                                + "'");
511
                        }
505 512

  
506 513
                        File prjFile = SHP.getPrjFile(shpParams.getSHPFile());
507 514
                        if (prjFile.exists()) {
......
516 523
                        FileUtils.moveFile(tmpParams.getDBFFile(), shpParams.getDBFFile());
517 524
                        FileUtils.moveFile(tmpParams.getSHPFile(), shpParams.getSHPFile());
518 525
                        FileUtils.moveFile(tmpParams.getSHXFile(), shpParams.getSHXFile());
526
                        FileUtils.moveFile(tmpParams.getCPGFile(), shpParams.getCPGFile());
519 527

  
520 528
                        savePrjFile(shpParams.getFile(), tmpParams.getCRS());
521 529

  
org.gvsig.desktop.library/org.gvsig.exportto/org.gvsig.exportto.swing/org.gvsig.exportto.swing.prov/org.gvsig.exportto.swing.prov.shape/pom.xml (copia de trabajo)
29 29
    </dependency>
30 30
    <dependency>
31 31
      <groupId>org.gvsig</groupId>
32
      <artifactId>org.gvsig.exportto.swing.prov.dbf</artifactId>
33
      <scope>compile</scope>
34
    </dependency>
35
    <dependency>
36
      <groupId>org.gvsig</groupId>
32 37
      <artifactId>org.gvsig.fmap.dal.api</artifactId>
33 38
      <scope>compile</scope>
34 39
    </dependency>
org.gvsig.desktop.library/org.gvsig.exportto/org.gvsig.exportto.swing/org.gvsig.exportto.swing.prov/org.gvsig.exportto.swing.prov.shape/src/main/java/org/gvsig/exportto/swing/prov/shape/ExporttoShapeProvider.java (copia de trabajo)
24 24
package org.gvsig.exportto.swing.prov.shape;
25 25

  
26 26
import org.cresques.cts.IProjection;
27

  
28 27
import org.gvsig.exportto.ExporttoService;
28
import org.gvsig.exportto.swing.prov.dbf.ExporttoDBFService;
29
import org.gvsig.exportto.swing.prov.dbf.panel.ExporttoDBFPanel;
29 30
import org.gvsig.exportto.swing.prov.file.AbstractExporttoFileProvider;
30 31
import org.gvsig.exportto.swing.spi.ExporttoSwingProvider;
31 32
import org.gvsig.fmap.dal.feature.FeatureStore;
......
50 51
     */
51 52
    public ExporttoShapeProvider(ProviderServices providerServices,
52 53
        FeatureStore featureStore, IProjection projection) {
53
        super(providerServices, featureStore, projection);
54
        super(providerServices, featureStore, projection, new ExporttoDBFPanel());
54 55
    }
55 56

  
56 57
    public ExporttoService createExporttoService() {
57 58
        return new ExporttoShapeService(
58
            selectFileOptionPanel, featureStore, projection);
59
            selectFileOptionPanel, featureStore, projection, ((ExporttoDBFPanel) selectFileOptionPanel).getEncoding());
59 60
    }
60 61
}
org.gvsig.desktop.library/org.gvsig.exportto/org.gvsig.exportto.swing/org.gvsig.exportto.swing.prov/org.gvsig.exportto.swing.prov.shape/src/main/java/org/gvsig/exportto/swing/prov/shape/ExporttoShapeService.java (copia de trabajo)
35 35

  
36 36
import org.cresques.cts.ICoordTrans;
37 37
import org.cresques.cts.IProjection;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

  
41 38
import org.gvsig.exportto.ExporttoService;
42 39
import org.gvsig.exportto.ExporttoServiceException;
43 40
import org.gvsig.exportto.ExporttoServiceFinishAction;
......
79 76
import org.gvsig.tools.dispose.DisposableIterator;
80 77
import org.gvsig.tools.dispose.DisposeUtils;
81 78
import org.gvsig.tools.task.AbstractMonitorableTask;
79
import org.slf4j.Logger;
80
import org.slf4j.LoggerFactory;
82 81

  
83 82

  
84 83
/**
......
102 101
    private NewFeatureStoreParameters newFeatureStoreParameters;
103 102
    private FilesystemServerExplorer filesystemServerExplorer;
104 103
    private SelectFileOptionPanel filePanel = null;
104
    private String encoding = null;
105 105

  
106 106
    private static GeometryManager geoManager = GeometryLocator.getGeometryManager();
107 107

  
......
112 112
    		FeatureStore featureStore,
113 113
    		IProjection projection) {
114 114

  
115
    	this(fPanel, featureStore, projection, null);
116
    }
117
    
118
    public ExporttoShapeService(
119
    		SelectFileOptionPanel fPanel,
120
    		FeatureStore featureStore,
121
    		IProjection projection,
122
    		String encoding) {
123

  
115 124
        super("Export to shape");
116 125
        this.featureStore = featureStore;
117 126
        this.filePanel = fPanel;
118 127
        this.theShapeFile = fPanel.getSelectedFile();
119 128
        this.projection = projection;
129
        this.encoding = encoding;
120 130

  
121 131
        try {
122 132
			origNameToDbfName = getNames(featureStore.getDefaultFeatureType());
......
356 366
        }
357 367

  
358 368
        newFeatureStoreParameters.setDynValue("CRS", projection);
369
        newFeatureStoreParameters.setDynValue("encoding", encoding);
359 370

  
360 371
        geometryType =
361 372
            featureSet.getDefaultFeatureType().getDefaultGeometryAttribute()