CSVTableProvider implements MessageBodyReader<CSVTable>,MessageBodyWriter<CSVTable> { @Override public CSVTable readFrom(final Class<CSVTable> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException, WebApplicationException { final Charset charset = Charset.forName(coalesce(mediaType.getParameters().get("charset"), "ISO-8859-15")); final Reader r = new BufferedReader(new InputStreamReader(entityStream, charset), 16384); final boolean headerPresent = CSVTable.HEADER_PRESENT.right().equalsIgnoreCase(mediaType.getParameters().get(CSVTable.HEADER_PRESENT.first())); boolean useAlternateSeparator = CSVTableProvider.INVERT_ALTERNATE_SEPARATOR.value().booleanValue(); final String temp = mediaType.getParameters().get("use-alternate-separator"); if (temp != null) { if (BooleanValueTypeFactory.SHARED_INSTANCE.create(temp).booleanValue()) { useAlternateSeparator = !useAlternateSeparator; } } else if (CSVTableProvider.USE_GERMAN_SEPARATOR_DETECTION.value().booleanValue() && coalesce(httpHeaders.getFirst("Content-Language"), "en").equals("de")) { useAlternateSeparator = true; } else if (CSVTableProvider.USE_SEPARATOR_AUTO_GUESS.value().booleanValue() && r.markSupported()) { r.mark(8192); try { final int[] commaCount = getRecordsLength(new CSVRecordReader(r, CSVSeparator.SEMICOLON), 2); r.reset(); final int[] semicolonCount = getRecordsLength(new CSVRecordReader(r, CSVSeparator.SEMICOLON), 2); if (commaCount[0] == commaCount[1]) { if (semicolonCount[0] == semicolonCount[1]) { if (commaCount[0] < semicolonCount[0]) { useAlternateSeparator = true; } else { useAlternateSeparator = false; } } else { useAlternateSeparator = false; } } else if (semicolonCount[0] == semicolonCount[1]) { useAlternateSeparator = true; } else if (headerPresent) { if (commaCount[0] < semicolonCount[0]) { useAlternateSeparator = true; } else { useAlternateSeparator = false; } } } catch (final Exception e) { this.logger.log(Level.WARNING, "Exception thrown in guessing the separator upon reading the first lines", e); } finally { r.reset(); } } final CSVParser p = new CSVParser(headerPresent, useAlternateSeparator ? ';' : ',', true); return p.parse(r); }  @Override boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType); @Override CSVTable readFrom(final Class<CSVTable> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream); @Override boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType); @Override long getSize(final CSVTable csvRecords, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType); @Override void writeTo(final CSVTable csvTable, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType,
			final MultivaluedMap<String, Object> responseHeaders, final OutputStream entityStream); static final String USE_SEMICOLON_AS_STANDARD_PROPERTY; static final SystemProperty<Boolean> INVERT_ALTERNATE_SEPARATOR; static final String GERMAN_GUESS_PROPERTY; static final SystemProperty<Boolean> USE_GERMAN_SEPARATOR_DETECTION; static final String AUTO_GUESS_PROPERTY; static final SystemProperty<Boolean> USE_SEPARATOR_AUTO_GUESS; }
@Test public void testReadFrom() throws IOException { System.setProperty(CSVTableProvider.AUTO_GUESS_PROPERTY, "yes"); Assert.assertFalse(isSemicolonDetected(this.commaEasy)); Assert.assertTrue(isSemicolonDetected(this.semicolonEasy)); Assert.assertFalse(isSemicolonDetected(this.commaHarder)); Assert.assertTrue(isSemicolonDetected(this.semicolonHarder)); }