You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2016/12/19 01:20:30 UTC
cxf git commit: CXF-7180: Implement JAX-RS 2.1 NIO Proposal
(Server/Reader)
Repository: cxf
Updated Branches:
refs/heads/master 1e89d332a -> 440538282
CXF-7180: Implement JAX-RS 2.1 NIO Proposal (Server/Reader)
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/44053828
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/44053828
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/44053828
Branch: refs/heads/master
Commit: 440538282e39c9da528101968cade1e7dcb32e0e
Parents: 1e89d33
Author: reta <dr...@gmail.com>
Authored: Sun Dec 18 20:20:06 2016 -0500
Committer: reta <dr...@gmail.com>
Committed: Sun Dec 18 20:20:06 2016 -0500
----------------------------------------------------------------------
.../org/apache/cxf/jaxrs/impl/RequestImpl.java | 29 ++-
.../cxf/jaxrs/nio/DelegatingNioInputStream.java | 85 +++++++
.../org/apache/cxf/jaxrs/nio/NioReadEntity.java | 47 ++++
.../cxf/jaxrs/nio/NioReadListenerImpl.java | 60 +++++
.../cxf/systest/jaxrs/nio/NioBookStore.java | 47 ++++
.../cxf/systest/jaxrs/nio/NioBookStoreTest.java | 15 ++
.../jaxrs/src/test/resources/files/books.txt | 245 +++++++++++++++++++
7 files changed, 520 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/44053828/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
index e57f3e0..9f25400 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
@@ -19,6 +19,7 @@
package org.apache.cxf.jaxrs.impl;
+import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
@@ -28,6 +29,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.HttpHeaders;
@@ -41,10 +43,13 @@ import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Variant;
import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxrs.nio.NioReadEntity;
+import org.apache.cxf.jaxrs.nio.NioReadListenerImpl;
import org.apache.cxf.jaxrs.utils.HttpUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.transport.http.AbstractHTTPDestination;
/**
* TODO : deal with InvalidStateExceptions
@@ -387,22 +392,30 @@ public class RequestImpl implements Request {
}
@Override
- public void entity(NioReaderHandler arg0) {
- // TODO: Implementation required (JAX-RS 2.1)
+ public void entity(NioReaderHandler reader) {
+ entity(reader, in -> { }, throwable -> { });
}
@Override
- public void entity(NioReaderHandler arg0, NioCompletionHandler arg1) {
- // TODO: Implementation required (JAX-RS 2.1)
+ public void entity(NioReaderHandler reader, NioCompletionHandler completion) {
+ entity(reader, completion, throwable -> { });
}
@Override
- public void entity(NioReaderHandler arg0, NioErrorHandler arg1) {
- // TODO: Implementation required (JAX-RS 2.1)
+ public void entity(NioReaderHandler reader, NioErrorHandler error) {
+ entity(reader, in -> { }, error);
}
@Override
- public void entity(NioReaderHandler arg0, NioCompletionHandler arg1, NioErrorHandler arg2) {
- // TODO: Implementation required (JAX-RS 2.1)
+ public void entity(NioReaderHandler reader, NioCompletionHandler completion, NioErrorHandler error) {
+ try {
+ final HttpServletRequest request = (HttpServletRequest)m.get(AbstractHTTPDestination.HTTP_REQUEST);
+ if (request != null) {
+ final NioReadEntity entity = new NioReadEntity(reader, completion, error);
+ request.getInputStream().setReadListener(new NioReadListenerImpl(entity, request.getInputStream()));
+ }
+ } catch (final IOException ex) {
+ throw new RuntimeException("Unable to initialize NIO entity", ex);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/44053828/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/DelegatingNioInputStream.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/DelegatingNioInputStream.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/DelegatingNioInputStream.java
new file mode 100644
index 0000000..f7b64ec
--- /dev/null
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/DelegatingNioInputStream.java
@@ -0,0 +1,85 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.nio;
+
+import java.io.IOException;
+
+import javax.servlet.ServletInputStream;
+import javax.ws.rs.core.NioInputStream;
+
+public class DelegatingNioInputStream extends NioInputStream {
+ private final ServletInputStream in;
+
+ public DelegatingNioInputStream(final ServletInputStream in) {
+ this.in = in;
+ }
+
+ @Override
+ public boolean isFinished() {
+ return in.isFinished();
+ }
+
+ @Override
+ public int read() throws IOException {
+ return in.read();
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ return in.read(b, off, len);
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ return in.read(b);
+ }
+
+ @Override
+ public synchronized void reset() throws IOException {
+ in.reset();
+ }
+
+ @Override
+ public void close() throws IOException {
+ in.close();
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ return in.skip(n);
+ }
+ @Override
+ public int available() throws IOException {
+ return in.available();
+ }
+
+ @Override
+ public synchronized void mark(int readlimit) {
+ in.mark(readlimit);
+ }
+
+ @Override
+ public boolean markSupported() {
+ return in.markSupported();
+ }
+
+ public boolean isReady() {
+ return in.isReady();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/44053828/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java
new file mode 100644
index 0000000..00857f0
--- /dev/null
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.nio;
+
+import javax.ws.rs.core.NioCompletionHandler;
+import javax.ws.rs.core.NioErrorHandler;
+import javax.ws.rs.core.NioReaderHandler;
+
+public class NioReadEntity {
+ private final NioReaderHandler reader;
+ private final NioCompletionHandler completion;
+ private final NioErrorHandler error;
+
+ public NioReadEntity(NioReaderHandler reader, NioCompletionHandler completion, NioErrorHandler error) {
+ this.reader = reader;
+ this.completion = completion;
+ this.error = error;
+ }
+
+ public NioReaderHandler getReader() {
+ return reader;
+ }
+
+ public NioCompletionHandler getCompletion() {
+ return completion;
+ }
+
+ public NioErrorHandler getError() {
+ return error;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/44053828/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java
new file mode 100644
index 0000000..47a4d8d
--- /dev/null
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.nio;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+
+public final class NioReadListenerImpl implements ReadListener {
+ private static final Logger LOG = LogUtils.getL7dLogger(NioReadListenerImpl.class);
+ private final NioReadEntity entity;
+ private final DelegatingNioInputStream in;
+
+ public NioReadListenerImpl(NioReadEntity entity, ServletInputStream in) {
+ this.entity = entity;
+ this.in = new DelegatingNioInputStream(in);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ try {
+ entity.getError().error(t);
+ } catch (final Throwable ex) {
+ LOG.warning("NIO NioReadListener error: " + ExceptionUtils.getStackTrace(ex));
+ }
+ }
+
+ @Override
+ public void onDataAvailable() throws IOException {
+ while (in.isReady() && !in.isFinished()) {
+ entity.getReader().read(in);
+ }
+ }
+
+ @Override
+ public void onAllDataRead() throws IOException {
+ entity.getCompletion().complete(in);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/44053828/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java
index e4a0c05..d6c6748 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java
@@ -19,14 +19,22 @@
package org.apache.cxf.systest.jaxrs.nio;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.concurrent.atomic.LongAdder;
+import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import org.apache.cxf.annotations.UseNio;
@@ -75,4 +83,43 @@ public class NioBookStore {
public InputStream readBooksFromInputStream() throws IOException {
return getClass().getResourceAsStream("/files/books.txt");
}
+
+ @POST
+ @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+ @Produces(MediaType.TEXT_PLAIN)
+ public void uploadBooks(@Context Request request, @Suspended AsyncResponse response) {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final byte[] buffer = new byte[4096];
+ final LongAdder adder = new LongAdder();
+
+ request.entity(
+ in -> {
+ try {
+ final int n = in.read(buffer);
+ if (n > 0) {
+ adder.add(n);
+ out.write(buffer, 0, n);
+ }
+ } catch (IOException e) {
+ throw new WebApplicationException(e);
+ }
+ },
+ in -> {
+ try {
+ if (!in.isFinished()) {
+ throw new IllegalStateException("Reader did not finish yet");
+ }
+
+ out.close();
+ response.resume("Book Store uploaded: " + adder.longValue() + " bytes");
+ } catch (IOException e) {
+ throw new WebApplicationException(e);
+ }
+ },
+ throwable -> { // error handler
+ System.out.println("Problem found: " + throwable.getMessage());
+ throw throwable;
+ }
+ );
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/44053828/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStoreTest.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStoreTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStoreTest.java
index c1743e3..efd9c4d 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStoreTest.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStoreTest.java
@@ -19,6 +19,7 @@
package org.apache.cxf.systest.jaxrs.nio;
+import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@@ -72,6 +73,20 @@ public class NioBookStoreTest extends AbstractBusClientServerTestBase {
}
}
+ @Test
+ public void testPostBookStore() throws IOException {
+ final Response response = createWebClient("/bookstore", MediaType.TEXT_PLAIN)
+ .type(MediaType.APPLICATION_OCTET_STREAM)
+ .post(IOUtils.readBytesFromStream(getClass().getResourceAsStream("/files/books.txt")));
+
+ try {
+ assertEquals(200, response.getStatus());
+ assertThat(response.readEntity(String.class), equalTo("Book Store uploaded: 10355 bytes"));
+ } finally {
+ response.close();
+ }
+ }
+
protected WebClient createWebClient(final String url, final String mediaType) {
final List< ? > providers = Arrays.asList(new JacksonJsonProvider());
http://git-wip-us.apache.org/repos/asf/cxf/blob/44053828/systests/jaxrs/src/test/resources/files/books.txt
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/resources/files/books.txt b/systests/jaxrs/src/test/resources/files/books.txt
index 6f23352..aedd064 100644
--- a/systests/jaxrs/src/test/resources/files/books.txt
+++ b/systests/jaxrs/src/test/resources/files/books.txt
@@ -2,3 +2,248 @@ Molecular Breeding and Nutritional Aspects of Buckwheat
{Progress in Heterocyclic Chemistry, Volume 28}
Pharmacology and Therapeutics for Dentistry
Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+Molecular Breeding and Nutritional Aspects of Buckwheat
+{Progress in Heterocyclic Chemistry, Volume 28}
+Pharmacology and Therapeutics for Dentistry
+Plotkin's Vaccines
+