[JAVA-29427] Consolidate libraries modules (#15536)

This commit is contained in:
panos-kakos
2024-01-03 20:39:23 +02:00
committed by GitHub
parent 5c6e53c15a
commit 21d3e16584
60 changed files with 364 additions and 453 deletions
@@ -0,0 +1,43 @@
package com.baeldung.fj;
import fj.F;
import fj.F1Functions;
import fj.Unit;
import fj.data.IO;
import fj.data.IOFunctions;
public class FunctionalJavaIOMain {
public static IO<Unit> printLetters(final String s) {
return () -> {
for (int i = 0; i < s.length(); i++) {
System.out.println(s.charAt(i));
}
return Unit.unit();
};
}
public static void main(String[] args) {
F<String, IO<Unit>> printLetters = i -> printLetters(i);
IO<Unit> lowerCase = IOFunctions.stdoutPrintln("What's your first Name ?");
IO<Unit> input = IOFunctions.stdoutPrint("First Name: ");
IO<Unit> userInput = IOFunctions.append(lowerCase, input);
IO<String> readInput = IOFunctions.stdinReadLine();
F<String, String> toUpperCase = i -> i.toUpperCase();
F<String, IO<Unit>> transformInput = F1Functions.<String, IO<Unit>, String> o(printLetters).f(toUpperCase);
IO<Unit> readAndPrintResult = IOFunctions.bind(readInput, transformInput);
IO<Unit> program = IOFunctions.bind(userInput, nothing -> readAndPrintResult);
IOFunctions.toSafe(program).run();
}
}
@@ -0,0 +1,48 @@
package com.baeldung.fj;
import fj.F;
import fj.Show;
import fj.data.Array;
import fj.data.List;
import fj.data.Option;
import fj.function.Characters;
import fj.function.Integers;
public class FunctionalJavaMain {
public static final F<Integer, Boolean> isEven = i -> i % 2 == 0;
public static void main(String[] args) {
List<Integer> fList = List.list(3, 4, 5, 6);
List<Boolean> evenList = fList.map(isEven);
Show.listShow(Show.booleanShow).println(evenList);
fList = fList.map(i -> i + 1);
Show.listShow(Show.intShow).println(fList);
Array<Integer> a = Array.array(17, 44, 67, 2, 22, 80, 1, 27);
Array<Integer> b = a.filter(Integers.even);
Show.arrayShow(Show.intShow).println(b);
Array<String> array = Array.array("Welcome", "To", "baeldung");
Boolean isExist = array.exists(s -> List.fromString(s).forall(Characters.isLowerCase));
System.out.println(isExist);
Array<Integer> intArray = Array.array(17, 44, 67, 2, 22, 80, 1, 27);
int sum = intArray.foldLeft(Integers.add, 0);
System.out.println(sum);
Option<Integer> n1 = Option.some(1);
Option<Integer> n2 = Option.some(2);
F<Integer, Option<Integer>> f1 = i -> i % 2 == 0 ? Option.some(i + 100) : Option.none();
Option<Integer> result1 = n1.bind(f1);
Option<Integer> result2 = n2.bind(f1);
Show.optionShow(Show.intShow).println(result1);
Show.optionShow(Show.intShow).println(result2);
}
}
@@ -0,0 +1,184 @@
package com.baeldung.javapoet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.IntStream;
import javax.lang.model.element.Modifier;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
public class PersonGenerator {
private static final String FOUR_WHITESPACES = " ";
private static final String PERSON_PACKAGE_NAME = "com.baeldung.javapoet.test.person";
private File outputFile;
public PersonGenerator() {
outputFile = new File(getOutputPath().toUri());
}
public static String getPersonPackageName() {
return PERSON_PACKAGE_NAME;
}
public Path getOutputPath() {
return Paths.get(new File(".").getAbsolutePath() + "/gensrc");
}
public FieldSpec getDefaultNameField() {
return FieldSpec
.builder(String.class, "DEFAULT_NAME")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$S", "Alice")
.build();
}
public MethodSpec getSortByLengthMethod() {
return MethodSpec
.methodBuilder("sortByLength")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(ParameterSpec
.builder(ParameterizedTypeName.get(ClassName.get(List.class), TypeName.get(String.class)), "strings")
.build())
.addStatement("$T.sort($N, $L)", Collections.class, "strings", getComparatorAnonymousClass())
.build();
}
public MethodSpec getPrintNameMultipleTimesMethod() {
return MethodSpec
.methodBuilder("printNameMultipleTimes")
.addModifiers(Modifier.PUBLIC)
.addCode(getPrintNameMultipleTimesLambdaImpl())
.build();
}
public CodeBlock getPrintNameMultipleTimesImpl() {
return CodeBlock
.builder()
.beginControlFlow("for (int i = $L; i < $L; i++)")
.addStatement("System.out.println(name)")
.endControlFlow()
.build();
}
public CodeBlock getPrintNameMultipleTimesLambdaImpl() {
return CodeBlock
.builder()
.addStatement("$T<$T> names = new $T<>()", List.class, String.class, ArrayList.class)
.addStatement("$T.range($L, $L).forEach(i -> names.add(name))", IntStream.class, 0, 10)
.addStatement("names.forEach(System.out::println)")
.build();
}
public TypeSpec getGenderEnum() {
return TypeSpec
.enumBuilder("Gender")
.addModifiers(Modifier.PUBLIC)
.addEnumConstant("MALE")
.addEnumConstant("FEMALE")
.addEnumConstant("UNSPECIFIED")
.build();
}
public TypeSpec getPersonInterface() {
return TypeSpec
.interfaceBuilder("Person")
.addModifiers(Modifier.PUBLIC)
.addField(getDefaultNameField())
.addMethod(MethodSpec
.methodBuilder("getName")
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
.returns(String.class)
.build())
.addMethod(MethodSpec
.methodBuilder("getDefaultName")
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.returns(String.class)
.addCode(CodeBlock
.builder()
.addStatement("return DEFAULT_NAME")
.build())
.build())
.build();
}
public TypeSpec getStudentClass() {
return TypeSpec
.classBuilder("Student")
.addSuperinterface(ClassName.get(PERSON_PACKAGE_NAME, "Person"))
.addModifiers(Modifier.PUBLIC)
.addField(FieldSpec
.builder(String.class, "name")
.addModifiers(Modifier.PRIVATE)
.build())
.addMethod(MethodSpec
.methodBuilder("getName")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return this.name")
.build())
.addMethod(MethodSpec
.methodBuilder("setName")
.addParameter(String.class, "name")
.addModifiers(Modifier.PUBLIC)
.addStatement("this.name = name")
.build())
.addMethod(getPrintNameMultipleTimesMethod())
.addMethod(getSortByLengthMethod())
.build();
}
public TypeSpec getComparatorAnonymousClass() {
return TypeSpec
.anonymousClassBuilder("")
.addSuperinterface(ParameterizedTypeName.get(Comparator.class, String.class))
.addMethod(MethodSpec
.methodBuilder("compare")
.addModifiers(Modifier.PUBLIC)
.addAnnotation(Override.class)
.addParameter(String.class, "a")
.addParameter(String.class, "b")
.returns(int.class)
.addStatement("return a.length() - b.length()")
.build())
.build();
}
public void generateGenderEnum() throws IOException {
writeToOutputFile(getPersonPackageName(), getGenderEnum());
}
public void generatePersonInterface() throws IOException {
writeToOutputFile(getPersonPackageName(), getPersonInterface());
}
public void generateStudentClass() throws IOException {
writeToOutputFile(getPersonPackageName(), getStudentClass());
}
private void writeToOutputFile(String packageName, TypeSpec typeSpec) throws IOException {
JavaFile javaFile = JavaFile
.builder(packageName, typeSpec)
.indent(FOUR_WHITESPACES)
.build();
javaFile.writeTo(outputFile);
}
}
@@ -0,0 +1,30 @@
package com.baeldung.r;
/**
* FastR showcase.
*
* @author Donato Rimenti
*/
public class FastRMean {
/**
* Invokes the customMean R function passing the given values as arguments.
*
* @param values the input to the mean script
* @return the result of the R script
*/
public double mean(int[] values) {
Context polyglot = Context.newBuilder()
.allowAllAccess(true)
.build();
String meanScriptContent = RUtils.getMeanScriptContent();
polyglot.eval("R", meanScriptContent);
Value rBindings = polyglot.getBindings("R");
Value rInput = rBindings.getMember("c")
.execute(values);
return rBindings.getMember("customMean")
.execute(rInput)
.asDouble();
}
}
@@ -0,0 +1,37 @@
package com.baeldung.r;
import java.io.IOException;
import java.net.URISyntaxException;
import com.github.rcaller.rstuff.RCaller;
import com.github.rcaller.rstuff.RCallerOptions;
import com.github.rcaller.rstuff.RCode;
/**
* RCaller showcase.
*
* @author Donato Rimenti
*/
public class RCallerMean {
/**
* Invokes the customMean R function passing the given values as arguments.
*
* @param values the input to the mean script
* @return the result of the R script
* @throws IOException if any error occurs
* @throws URISyntaxException if any error occurs
*/
public double mean(int[] values) throws IOException, URISyntaxException {
String fileContent = RUtils.getMeanScriptContent();
RCode code = RCode.create();
code.addRCode(fileContent);
code.addIntArray("input", values);
code.addRCode("result <- customMean(input)");
RCaller caller = RCaller.create(code, RCallerOptions.create());
caller.runAndReturnResult("result");
return caller.getParser()
.getAsDoubleArray("result")[0];
}
}
@@ -0,0 +1,33 @@
package com.baeldung.r;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
/**
* Utility class for loading the script.R content.
*
* @author Donato Rimenti
*/
public class RUtils {
/**
* Loads the script.R and returns its content as a string.
*
* @return the script.R content as a string
* @throws IOException if any error occurs
* @throws URISyntaxException if any error occurs
*/
static String getMeanScriptContent() throws IOException, URISyntaxException {
URI rScriptUri = RUtils.class.getClassLoader()
.getResource("script.R")
.toURI();
Path inputScript = Paths.get(rScriptUri);
return Files.lines(inputScript)
.collect(Collectors.joining());
}
}
@@ -0,0 +1,36 @@
package com.baeldung.r;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.script.ScriptException;
import org.renjin.script.RenjinScriptEngine;
import org.renjin.sexp.DoubleArrayVector;
/**
* Renjin showcase.
*
* @author Donato Rimenti
*/
public class RenjinMean {
/**
* Invokes the customMean R function passing the given values as arguments.
*
* @param values the input to the mean script
* @return the result of the R script
* @throws IOException if any error occurs
* @throws URISyntaxException if any error occurs
* @throws ScriptException if any error occurs
*/
public double mean(int[] values) throws IOException, URISyntaxException, ScriptException {
RenjinScriptEngine engine = new RenjinScriptEngine();
String meanScriptContent = RUtils.getMeanScriptContent();
engine.put("input", values);
engine.eval(meanScriptContent);
DoubleArrayVector result = (DoubleArrayVector) engine.eval("customMean(input)");
return result.asReal();
}
}
@@ -0,0 +1,30 @@
package com.baeldung.r;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.REngineException;
import org.rosuda.REngine.Rserve.RConnection;
/**
* Rserve showcase.
*
* @author Donato Rimenti
*/
public class RserveMean {
/**
* Connects to the Rserve istance listening on 127.0.0.1:6311 and invokes the
* customMean R function passing the given values as arguments.
*
* @param values the input to the mean script
* @return the result of the R script
* @throws REngineException if any error occurs
* @throws REXPMismatchException if any error occurs
*/
public double mean(int[] values) throws REngineException, REXPMismatchException {
RConnection c = new RConnection();
c.assign("input", values);
return c.eval("customMean(input)")
.asDouble();
}
}
@@ -0,0 +1,98 @@
package com.baeldung.sbe;
import java.util.StringJoiner;
import com.baeldung.sbe.stub.Currency;
import com.baeldung.sbe.stub.Market;
public class MarketData {
private final int amount;
private final double price;
private final Market market;
private final Currency currency;
private final String symbol;
public MarketData(int amount, double price, Market market, Currency currency, String symbol) {
this.amount = amount;
this.price = price;
this.market = market;
this.currency = currency;
this.symbol = symbol;
}
public static class Builder {
private int amount;
public Builder amount(int amount) {
this.amount = amount;
return this;
}
private double price;
public Builder price(double price) {
this.price = price;
return this;
}
private Market market;
public Builder market(Market market) {
this.market = market;
return this;
}
private Currency currency;
public Builder currency(Currency currency) {
this.currency = currency;
return this;
}
private String symbol;
public Builder symbol(String symbol) {
this.symbol = symbol;
return this;
}
public MarketData build() {
return new MarketData(amount, price, market, currency, symbol);
}
}
public static Builder builder() {
return new Builder();
}
public int getAmount() {
return amount;
}
public double getPrice() {
return price;
}
public Market getMarket() {
return market;
}
public Currency getCurrency() {
return currency;
}
public String getSymbol() {
return symbol;
}
@Override
public String toString() {
return new StringJoiner(", ", MarketData.class.getSimpleName() + "[", "]").add("amount=" + amount)
.add("price=" + price)
.add("market=" + market)
.add("currency=" + currency)
.add("symbol='" + symbol + "'")
.toString();
}
}
@@ -0,0 +1,48 @@
package com.baeldung.sbe;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import com.baeldung.sbe.stub.Currency;
import com.baeldung.sbe.stub.Market;
public class MarketDataSource implements Iterator<MarketData> {
private final LinkedList<MarketData> dataQueue = new LinkedList<>();
public MarketDataSource() {
// adding some test data into queue
this.dataQueue.addAll(Arrays.asList(MarketData.builder()
.amount(1)
.market(Market.NASDAQ)
.symbol("AAPL")
.price(134.12)
.currency(Currency.USD)
.build(), MarketData.builder()
.amount(2)
.market(Market.NYSE)
.symbol("IBM")
.price(128.99)
.currency(Currency.USD)
.build(), MarketData.builder()
.amount(1)
.market(Market.NASDAQ)
.symbol("AXP")
.price(34.87)
.currency(Currency.EUR)
.build()));
}
@Override
public boolean hasNext() {
return !this.dataQueue.isEmpty();
}
@Override
public MarketData next() {
final MarketData data = this.dataQueue.pop();
this.dataQueue.add(data);
return data;
}
}
@@ -0,0 +1,92 @@
package com.baeldung.sbe;
import java.nio.ByteBuffer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MarketDataStreamServer {
private static final Logger log = LoggerFactory.getLogger(MarketDataStreamServer.class);
ByteBuffer buffer = ByteBuffer.allocate(128);
final AtomicLong writePos = new AtomicLong();
ScheduledExecutorService writerThread = Executors.newScheduledThreadPool(1);
ScheduledExecutorService readerThreadPool = Executors.newScheduledThreadPool(2);
private class Client {
final String name;
final ByteBuffer readOnlyBuffer;
final AtomicLong readPos = new AtomicLong();
Client(String name, ByteBuffer source) {
this.name = name;
this.readOnlyBuffer = source.asReadOnlyBuffer();
}
void readTradeData() {
while (readPos.get() < writePos.get()) {
try {
final int pos = this.readOnlyBuffer.position();
final MarketData data = MarketDataUtil.readAndDecode(this.readOnlyBuffer);
readPos.addAndGet(this.readOnlyBuffer.position() - pos);
log.info("<readTradeData> client: {}, read/write gap: {}, data: {}", name, writePos.get() - readPos.get(), data);
} catch (IndexOutOfBoundsException e) {
this.readOnlyBuffer.clear(); // ring buffer
} catch (Exception e) {
log.error("<readTradeData> cannot read from buffer {}", readOnlyBuffer);
}
}
if (this.readOnlyBuffer.remaining() == 0) {
this.readOnlyBuffer.clear(); // ring buffer
}
}
void read() {
readerThreadPool.scheduleAtFixedRate(this::readTradeData, 1, 1, TimeUnit.SECONDS);
}
}
private Client newClient(String name) {
return new Client(name, buffer);
}
private void writeTradeData(MarketData data) {
try {
final int writtenBytes = MarketDataUtil.encodeAndWrite(buffer, data);
writePos.addAndGet(writtenBytes);
log.info("<writeTradeData> buffer size remaining: %{}, data: {}", 100 * buffer.remaining() / buffer.capacity(), data);
} catch (IndexOutOfBoundsException e) {
buffer.clear(); // ring buffer
writeTradeData(data);
} catch (Exception e) {
log.error("<writeTradeData> cannot write into buffer {}", buffer);
}
}
private void run(MarketDataSource source) {
writerThread.scheduleAtFixedRate(() -> {
if (source.hasNext()) {
writeTradeData(source.next());
}
}, 1, 2, TimeUnit.SECONDS);
}
public static void main(String[] args) {
MarketDataStreamServer server = new MarketDataStreamServer();
Client client1 = server.newClient("client1");
client1.read();
Client client2 = server.newClient("client2");
client2.read();
server.run(new MarketDataSource());
}
}
@@ -0,0 +1,78 @@
package com.baeldung.sbe;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import org.agrona.concurrent.UnsafeBuffer;
import com.baeldung.sbe.stub.MessageHeaderDecoder;
import com.baeldung.sbe.stub.MessageHeaderEncoder;
import com.baeldung.sbe.stub.TradeDataDecoder;
import com.baeldung.sbe.stub.TradeDataEncoder;
public class MarketDataUtil {
public static int encodeAndWrite(ByteBuffer buffer, MarketData marketData) {
final int pos = buffer.position();
final UnsafeBuffer directBuffer = new UnsafeBuffer(buffer);
final MessageHeaderEncoder headerEncoder = new MessageHeaderEncoder();
final TradeDataEncoder dataEncoder = new TradeDataEncoder();
final BigDecimal priceDecimal = BigDecimal.valueOf(marketData.getPrice());
final int priceMantis = priceDecimal.scaleByPowerOfTen(priceDecimal.scale())
.intValue();
final int priceExponent = priceDecimal.scale() * -1;
final TradeDataEncoder encoder = dataEncoder.wrapAndApplyHeader(directBuffer, pos, headerEncoder);
encoder.amount(marketData.getAmount());
encoder.quote()
.market(marketData.getMarket())
.currency(marketData.getCurrency())
.symbol(marketData.getSymbol())
.price()
.mantissa(priceMantis)
.exponent((byte) priceExponent);
// set position
final int encodedLength = headerEncoder.encodedLength() + encoder.encodedLength();
buffer.position(pos + encodedLength);
return encodedLength;
}
public static MarketData readAndDecode(ByteBuffer buffer) {
final int pos = buffer.position();
final UnsafeBuffer directBuffer = new UnsafeBuffer(buffer);
final MessageHeaderDecoder headerDecoder = new MessageHeaderDecoder();
final TradeDataDecoder dataDecoder = new TradeDataDecoder();
dataDecoder.wrapAndApplyHeader(directBuffer, pos, headerDecoder);
// set position
final int encodedLength = headerDecoder.encodedLength() + dataDecoder.encodedLength();
buffer.position(pos + encodedLength);
final double price = BigDecimal.valueOf(dataDecoder.quote()
.price()
.mantissa())
.scaleByPowerOfTen(dataDecoder.quote()
.price()
.exponent())
.doubleValue();
return MarketData.builder()
.amount(dataDecoder.amount())
.symbol(dataDecoder.quote()
.symbol())
.market(dataDecoder.quote()
.market())
.currency(dataDecoder.quote()
.currency())
.price(price)
.build();
}
}
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe"
package="com.baeldung.sbe.stub" id="1" version="0" semanticVersion="5.2" description="A schema represents stock market data.">
<types>
<composite name="messageHeader" description="Message identifiers and length of message root.">
<type name="blockLength" primitiveType="uint16"/>
<type name="templateId" primitiveType="uint16"/>
<type name="schemaId" primitiveType="uint16"/>
<type name="version" primitiveType="uint16"/>
</composite>
<enum name="Market" encodingType="uint8">
<validValue name="NYSE" description="New York Stock Exchange">0</validValue>
<validValue name="NASDAQ" description="National Association of Securities Dealers Automated Quotations">1</validValue>
</enum>
<type name="Symbol" primitiveType="char" length="4" characterEncoding="ASCII" description="Stock symbol"/>
<composite name="Decimal">
<type name="mantissa" primitiveType="uint64" minValue="0"/>
<type name="exponent" primitiveType="int8"/>
</composite>
<enum name="Currency" encodingType="uint8">
<validValue name="USD" description="US Dollar">0</validValue>
<validValue name="EUR" description="Euro">1</validValue>
</enum>
<composite name="Quote" description="A quote represents the price of a stock in a market">
<ref name="market" type="Market"/>
<ref name="symbol" type="Symbol"/>
<ref name="price" type="Decimal"/>
<ref name="currency" type="Currency"/>
</composite>
</types>
<sbe:message name="TradeData" id="1" description="Represents a quote and amount of trade">
<field name="quote" id="1" type="Quote"/>
<field name="amount" id="2" type="uint16"/>
</sbe:message>
</sbe:messageSchema>