Composition adapter implementation java - java

I have an external library:
public class ExternalLib { ... }
I want to use it in my project so I initiated it like this in the class I will use in my project:
public class Codec {
private static final ExternalLib externalLib = new ExternalLib();
public static String encode(String x, int l, Long s, int f) {
return externalLib.encode(x, l, s, f);
}
public static ExternalLib decode(String y) {
return externalLib.decode(y);
}
I would like to protect my class Codec in case anyone change sth in class ExternalLib, so was wondering how could I introduce here a new class/interface? and map the externalLib (in the body of decode method)? Was thinking about wrapping externalLib and than mapping it into new object that I will return when performing decode method. Anyone can help me with that?

Related

A way of accessing Windows MMDevice API from Java?

I would like to use the MMDevice API from my Java app. What are my options?
I tried to use JNA. Looks like I can't use JNA Typelib parsing because there no types for this API (Is there a COM type library for Windows Core Audio). As suggested, I need to provide my own declarations of the API.
So I also tried both JNA examples with manual declarations but they give "Interface not supported HRESULT=80004002" error:
public class MMDeviceAPITest {
public static void test1() {
try {
Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED);
var obj = new Test1.MMDeviceEnumerator(); // exception E_NOINTERFACE (HRESULT: 80004002)
// ...
} finally {
Ole32.INSTANCE.CoUninitialize();
}
}
public static void test2() {
try {
Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED);
var factory = new Factory();
var obj = factory.createObject(Test2.MMDeviceEnumerator.class); // exception E_NOINTERFACE (HRESULT: 80004002)
var in = obj.queryInterface(Test2.IMMDeviceEnumerator.class);
// ...
} finally {
Ole32.INSTANCE.CoUninitialize();
}
}
}
interface Test1 {
class MMDeviceEnumerator extends COMLateBindingObject {
public MMDeviceEnumerator() {
super(new Guid.CLSID("bcde0395-e52f-467c-8e3d-c4579291692e"), true);
}
}
}
interface Test2 {
#ComObject(clsId = "bcde0395-e52f-467c-8e3d-c4579291692e")
interface MMDeviceEnumerator extends IUnknown {} // doesn't extend IUnknown in C sources, probably it's the problem...
#ComInterface(iid = "a95664d2-9614-4f35-a746-de8db63617e6")
interface IMMDeviceEnumerator extends IUnknown {}
}
Any ideas how I could access this API from Java? Can I somehow create working declarations for JNA? Or use another framework maybe?
My last idea is to create/find a micro native app/library that wraps the needed COM calls, so I could call this app/library easily (via subprocesses or simple JNA declarations). I'm new to COM world, but it sounds working for me...
The docs you linked show how to create using CoCreateInstance:
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
hr = CoCreateInstance(
CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pEnumerator);
This should get you somewhere close with JNA.
class MMDeviceEnumerator extends Unknown {
public static final CLSID CLSID_MMDeviceEnumerator = new CLSID("bcde0395-e52f-467c-8e3d-c4579291692e");
public static final GUID IID_IMMDeviceEnumerator = new GUID("a95664d2-9614-4f35-a746-de8db63617e6");
public MMDeviceEnumerator(Pointer p) {
super(p);
}
public static MMDeviceEnumerator create() {
PointerByReference pEnumerator = new PointerByReference();
HRESULT hres = Ole32.INSTANCE.CoCreateInstance(
CLSID_MMDeviceEnumerator, null,
WTypes.CLSCTX_ALL, IID_IMMDeviceEnumerator,
pEnumerator);
if (COMUtils.FAILED(hres)) {
return null;
}
return new MMDeviceEnumerator(pEnumerator.getValue());
}
// map functions as needed
}
I used the implementation of IWbemContext in JNA as a template above. You can consult that class for example COM function mappings.
For some reason I can't suggest edits to the answer of Daniel Widdis. The answer worked for me, many thanks! Just wanted to show how to map one method as an example:
class MMDeviceEnumerator extends Unknown {
public static final CLSID CLSID_MMDeviceEnumerator = new CLSID("bcde0395-e52f-467c-8e3d-c4579291692e");
public static final GUID IID_IMMDeviceEnumerator = new GUID("a95664d2-9614-4f35-a746-de8db63617e6");
public MMDeviceEnumerator(Pointer p) {
super(p);
}
public static MMDeviceEnumerator create() {
PointerByReference pEnumerator = new PointerByReference();
HRESULT hres = Ole32.INSTANCE.CoCreateInstance(
CLSID_MMDeviceEnumerator, null,
WTypes.CLSCTX_ALL, IID_IMMDeviceEnumerator, pEnumerator);
if (COMUtils.FAILED(hres)) {
return null;
}
return new MMDeviceEnumerator(pEnumerator.getValue());
}
public static final int EDataFlow_eRender = 0;
public static final int EDataFlow_eCapture = 1;
public static final int EDataFlow_eAll = 2;
public static final int EDataFlow_enum_count = 3;
public static final int DEVICE_STATE_ACTIVE = 0x1;
public static final int DEVICE_STATE_DISABLED = 0x2;
public static final int DEVICE_STATE_NOTPRESENT = 0x4;
public static final int DEVICE_STATE_UNPLUGGED = 0x8;
public static final int DEVICE_STATEMASK_ALL = 0xF;
public void EnumAudioEndpoints(int dataFlow, int dwStateMask, PointerByReference ppDevices) {
WinNT.HRESULT res = (WinNT.HRESULT) _invokeNativeObject(
3, // `EnumAudioEndpoints` is the 3rd method of `IMMDeviceEnumeratorVtbl` in `mmdeviceapi.h`
new Object[] { getPointer(), dataFlow, new WinDef.DWORD(dwStateMask), ppDevices},
WinNT.HRESULT.class
);
COMUtils.checkRC(res);
}
// map other functions as needed
}

descriptive way of calling various feign APIs

I want to create a construct that would work with pageable feign api calls and dry them from the first page of declared size available to the last one.
To take in account:
the feign method calls can differ in arg. count tho last two is always page and it's size
data structure returned is similar to the extent of paging information, but core data list received type differs
This is what I did:
method that is a base for draining a particular api call:
public <T> List<BaseFeignResult<T>> drainFeignPageableCall(
PagedCall<T> feignCall
) {
BaseFeignResult<T> firstPage = feignCall.call(0, 10);
List<BaseFeignResult<T>> baseFeignResults = drainFeignPageableCall(feignCall, firstPage, Lists.newArrayList(firstPage), 1);
return baseFeignResults;
}
It's overload and continuation:
<T> List<BaseFeignResult<T>> drainFeignPageableCall(
PagedCall<T> feignCall,
BaseFeignResult<T> dataPage,
List<BaseFeignResult<T>> acc,
int page
) {
if (dataPage.resp.getBody().getData().size() % 10 > 0)
return acc;
BaseFeignResult<T> res = feignCall.call(page, 10);
acc.add(res);
return drainFeignPageableCall(feignCall, res, acc, ++page);
}
And the definitions:
public static class SingleParamPageableCall<T> implements PagedCall<T> {
SingleParamPagingApi<T> fun;
String param;
public SingleParamPageableCall(SingleParamPagingApi<T> fun, String param) {
this.fun = fun;
this.param = param;
}
#Override
public BaseFeignResult<T> call(int p, int s) {
BaseFeignResult.BaseFeignResultBuilder<T> builder = BaseFeignResult.builder();
try {
builder.resp(fun.callFeignApi(param, p, s));
} catch (RuntimeException e) {
builder.excp(e);
}
return builder.build();
}
}
public interface PagedCall<T> {
BaseFeignResult<T> call(int p, int s);
}
#Builder
public static class BaseFeignResult<T> {
private final ResponseEntity<IVDPagedResponseOf<T>> resp;
private final RuntimeException excp;
}
public interface SingleParamPagingApi<T> {
ResponseEntity<IVDPagedResponseOf<T>> callFeignApi(String arg, int page, int size) throws RuntimeException;
}
This can be arbitraliry called as:
drainFeignPageableCall(new BaseService.SingleParamPageableCall<GetOrderInfoDto>(ordersFeignClient::getOrdersBySampleIds, "34596"));
and works as expected.
So as you can see, if I want to keep some sort of abstraction above various drain-able per api calls, I need to introduce definitions like SingleParamPagingApi and class implementation of SingleParamPageableCall<T>. so with every other api to be treated this way, I would need to redefine those.
My question here is: how to do this in purely descripive way, or how to reimplement this as a functional programming?
to be clear: I would like to have code impl. in which I would describe how to map parameters to the method call (that can and will vary) and return a common data structure with the data being of generic type.
Basically I am looking for the most descriptive way of re-implementing this in Java without defining heavy objects like SingleParamPagingApi<T>, but describing how to mount params called with to API params itself rather.
Thank you!
This simplest way would be to replace your SingleParamPagingApi interface with one that has a method that just takes the page no and size as parameters (PagingApi). And replace SingleParamPageableCall with a class that just takes a PagingApi argument. Then you can create the variants of PagingApi for 1 parameter, 2 parameters etc by immediately binding the method to the argument 0, argument 1 etc, thereby creating a PagingApi instance (the of methods).
public interface PagingApi1<T, A0> {
ResponseEntity<IVDPagedResponseOf<T>> callFeignApi(A0 arg0, int page, int size) throws RuntimeException;
}
public interface PagingApi2<T, A0, A1> {
ResponseEntity<IVDPagedResponseOf<T>> callFeignApi(A0 arg0, A1 arg1, int page, int size) throws RuntimeException;
}
public interface PagingApi<T> {
static <T, A0> PagingApi<T> of(PagingApi1<T, A0> api, A0 arg0) {
return (p, s) -> api.callFeignApi(arg0, p, s);
}
static <T, A0, A1> PagingApi<T> of(PagingApi2<T, A0, A1> api, A0 arg0, A1 arg1,) {
return (p, s) -> api.callFeignApi(arg0, arg1, p, s);
}
ResponseEntity<IVDPagedResponseOf<T>> callFeignApi(int page, int size) throws RuntimeException;
}
public static class PageableCall<T> implements PagedCall<T> {
PagingApi<T> fun;
public PageableCall(PagingApi<T> fun) {
this.fun = fun;
}
#Override
public BaseFeignResult<T> call(int p, int s) {
BaseFeignResult.BaseFeignResultBuilder<T> builder = BaseFeignResult.builder();
try {
builder.resp(fun.callFeignApi(p, s));
} catch (RuntimeException e) {
builder.excp(e);
}
return builder.build();
}
}
You would call it as follows:
drainFeignPageableCall(
new PageableCall<GetOrderInfoDto>(
PagingApi.of(ordersFeignClient::getOrdersBySampleIds, "34596")
)
);
As a further simplifcation, you could probably collapse PagingApi and PagedCall into a single interface.
I would also suggest replacing the recursive calls in drainFeignPageableCall with a simple for loop. You might think recursion is more "functional" but it's needlessly complex and inefficient here.

Use SHGetFileInfo in Java with JNA

I tried to translate the SHGetFileInfo function from Shell32 into Java with JNA and used C# code and this as reference
While in the C# code psfi.iIcon is 432 in my translated Java code psfi.iIcon is 0. If I am right, for the same file they should be same no matter which language I use, shouldn't they?
My Java code:
public static void main(String[] args) {
String path = "[PATH_TO_EXE]\\test.exe"; //Of course in my code I used the real path
SHFILEINFO sfi = new SHFILEINFO();
DWORD_PTR i = Shell32.INSTANCE.SHGetFileInfo(path, 0, sfi, sfi.size(), SHGFI.SysIconIndex);
System.out.println(sfi.iIcon); //<-- Prints 0, should print 432
}
public static class SHGFI {
static final int SysIconIndex = 0x000004000;
static final int LargeIcon = 0x000000000;
static final int UseFileAttributes = 0x000000010;
}
public interface Shell32 extends StdCallLibrary {
Shell32 INSTANCE = Native.loadLibrary("shell32", Shell32.class, W32APIOptions.UNICODE_OPTIONS);
DWORD_PTR SHGetFileInfo(String pszPath, int dwFileAttributes, SHFILEINFO psfi, int cbFileInfo, int uFlags);
}
public static class SHFILEINFO extends Structure {
public HICON hIcon;
public int iIcon;
public DWORD dwAttributes;
public char[] szDisplayName = new char[260];
public char[] szTypeName = new char[80];
#Override
protected List<String> getFieldOrder() {
return Arrays.asList("hIcon", "iIcon", "dwAttributes", "szDisplayName", "szTypeName");
}
}
Is there anything fundemental that I did wrong? I'm new to JNA and Windows functions
Under the Remarks section, there is this piece of information, which imho might be the source of your problem
You must initialize Component Object Model (COM) with CoInitialize or
OleInitialize prior to calling SHGetFileInfo.
It's a pretty straightforward call
CoInitialize(null);
As DanielWiddis pointed out in the comments, per documentation
New applications should call CoInitializeEx instead of CoInitialize
And
To close the COM library gracefully, each successful call to
CoInitialize or CoInitializeEx, including those that return S_FALSE,
must be balanced by a corresponding call to CoUninitialize
Example
CoInitializeEx(null, 0);
CoUninitialize();

Separating protocol parser and handler in Java

I am working with a simple, binary protocol. Each packet consists of 10 bytes. The first byte specifies the packet type. There are many (~50) packet types used.
I want to write a general parser for this protocol which is independent of the handling of packets. So the parser should detect the packet type and put the data into an instance of the appropriate packet class, which holds the protocol data. E.g., considering the classes below: When parser detects packet type 1 --> new Type1() and read raw bytes and set temperature and humidity. Similarly for packet type 2 and all the other packet types.
class Packet {
byte[] raw;
}
class Type1 extends Packet {
int temperature;
int humidity;
}
class Type2 extends Packet {
DateTime sunrise;
DateTime sunset;
}
Since there are so many packet types but each application only uses very few, it should be possible to register for certain types before parsing starts. All other packets types are ignored.
I am planning to have a PacketParser for each packet type. Probably, I need a handler class for each type as well. E.g.:
abstract class Type1Parser {
abstract void handle(Type1 packet);
}
class Type1Parser extends PacketParser {
//how to use/set handler? how to pass packet to handler?
static public Type1Handler type1Handler = null;
#override
void parse(Packet input) {
if(type1Handler == null)
return;
Type1 packet = new Type1(input);
packet.temperature = byteToInt(input.raw, 0, 3);
packet.humidity = byteToInt(input.raw, 4, 7);
type1Handler.handle(packet);
}
}
How to connect parser and handler? Above a naive approach:
The program needs to implement Type1Handler and set the static variable Type1Parser.type1Handler.
Then the main parser can look like this:
class MainParser {
Type1Parser type1 = new Type1Parser();
Type2Parser type2 = new Type2Parser();
...
void parse(byte[] packet) {
switch(packet[0]) {
case 1: type1.parse(packet); break;
case 2: type2.parse(packet); break;
...
}
}
}
However, this seems to be 1) a lot of very similar lines of code 2) a lot of overhead, since all packet parser are instantiated and for each packet parse() is called, even if no handler is registered.
Any ideas how to improve this code?
Note: The parsing should be transparent to the program. Parsing code should stay inside the "parsing library". So ideally, the program only "knows" classes TypeXHandler and TypeX.
There is no perfect answer to this design question, and I don't wish to pretend that mine is, but hopefully my instinctual approach to this problem teaches you things you didn't already know! The main missing component from your code that I see is Generics:
public interface Parser<T extends Packet> {
T parse(Packet packet);
}
public interface Handler<T extends Packet> {
void handle(T packet);
}
This way, you can use lazy static initialization to manage which packet types you are aware of. I won't flesh out the code entirely here, but to give you an idea:
public class TypeRegistry {
private static Map<Integer, TypeHandlerBundle<?>> typeHandlerBundles;
static <T> register(int typeNum, Class<T> clazz, Parser<T> parser, Handler<T> handler) {
// Make bundle, add to map
}
... void parse(Packet packet) {
if (typeHandlerBundles.containsKey((int) packet[0])) {
TypeHandlerBundle<?> bundle = typeHandlerBundles.get((int) packet[0]);
bundle.parseAndHandle(packet);
}
}
}
public class TypeHandlerBundle<T extends Packet> {
...
private final Parser<T> parser;
private final Handler<T> handler;
... void parseAndHandle(Packet packet) {
T parsedPacket = parser.parse(packet);
handler.handle(parsedPacket);
}
}
...
public class Type1Processor {
static {
TypeRegistry.register(1, Type1.class, TYPE1_PARSER, TYPE1_HANDLER);
}
// Definition of constants, implementation, etc.
// ...
}
===
Things I omitted: Qualifiers, lower level implementation, Error-checking, Synchronization, main method, etc. Depending on your set-up, static initialization might not be the right way to call TypeRegistry.register, so you could instead consider a properties file that lists the classes (ugh, but has its merits), or a hard-coded sequence of calls in your main method.
Since Parser and Handler are functional interfaces here, don't forget that you can implement them with lambdas! You can save tons of lines of code that way.
You were right when you said that need one abstract class for parsing array of data.
package parser;
public abstract class TypeParser {
public abstract void parse(byte[] arr);
}
Then for every packet type( you said that you can have 50 but if the first byte indicates the type of packet then 256 deferent types are possible), you can create class as you need for certain type eg.. Type1Parser for type 1 Type122Parser for type 122.
package parser.type;
import parser.TypeParser;
public class Type1Parser extends TypeParser{
public void parse(byte[] array){
// do with the bytes of array what you want
}
}
package parser.type;
import parser.TypeParser;
public class Type122Parser extends TypeParser {
public void parse(byte[] arr) {}
}
Then you can have one class that represents the main parser for all. If you need for every income packet to have one object for later use then you can hold it in vector.
package parser;
import java.util.Vector;
public class MainParser {
private Vector<TypeParser> vecTypeParse=new Vector<TypeParser>();
public void parsePacket(byte[] array){
if(array==null || array.length<1) return; // or throw some exception
int typePacket=array[0]&0xff;
String s="parser.type.Type"+String.valueOf(typePacket)+"Parser";
TypeParser type=null;
try {
type=(TypeParser)Class.forName(s).newInstance(); //here you create class that you need
} catch(InstantiationException e) {e.printStackTrace();
} catch(IllegalAccessException e) {e.printStackTrace();
} catch(ClassNotFoundException e) {e.printStackTrace();}
// you can do something with the exceptons
if(type==null) return; // or throw some exception
type.parse(array); // here parse data for class you just created.
this.vecTypeParse.addElement(type);
}
}
Well, almost like torquestomp answer, here comes my code:
interface Packet {
}
interface PacketParser<T extends Packet> {
Class<T> getPacketClass();
int getPacketId();
int getPacketLength();
Packet parse(byte[] raw, int offset);
}
interface PacketListener<T extends Packet> {
Class<T> getPacketClass();
void onPacket(T packet);
}
interface PacketParsersRegistry {
<T extends Packet> void registerPacketParser(PacketParser<T> packetParser);
<T extends Packet> void registerPacketListener(PacketListener<T> packetListener);
}
class PacketHandlers<T extends Packet> {
final PacketParser<T> parser;
PacketListener<T> listener;
PacketHandlers(PacketParser<T> parser) {
this.parser = parser;
}
void setListener(PacketListener<T> listener) {
this.listener = listener;
}
}
class MainParser implements PacketParsersRegistry {
private final HashMap<Class<?>, PacketHandlers<?>> handlers = new HashMap<>();
private final HashMap<Integer, PacketParser> parsers = new HashMap<>();
#Override
public <T extends Packet> void registerPacketParser(PacketParser<T> packetParser) {
parsers.put(packetParser.getPacketId(), packetParser);
Class<T> packetClass = packetParser.getPacketClass();
handlers.put(packetClass, new PacketHandlers<>(packetParser));
}
#Override
public <T extends Packet> void registerPacketListener(PacketListener<T> packetListener) {
//noinspection unchecked
PacketHandlers<T> handlers = (PacketHandlers<T>) this.handlers.get(packetListener.getPacketClass());
if (handlers != null) {
handlers.setListener(packetListener);
}
}
void parse(byte[] stream, int offset) {
while (offset < stream.length) {
int type = stream[offset];
PacketParser parser = parsers.get(type);
// parser m.b. != null here
PacketListener listener = (PacketListener) handlers.get(parser.getPacketClass());
if (listener != null) {
Packet packet = parser.parse(stream, offset);
//noinspection unchecked
listener.onPacket(packet);
}
offset += parser.getPacketLength();
}
}
}
And here's how you can use it:
class HumidityPacket implements Packet {}
public class Main {
public static void main(String[] args) {
MainParser parser = new MainParser();
//...
parser.registerPacketListener(new PacketListener<HumidityPacket>() {
#Override
public Class<HumidityPacket> getPacketClass() {
return HumidityPacket.class;
}
#Override
public void onPacket(HumidityPacket packet) {
// todo
}
});
}
}

Generic static factory

I am getting a compilation error. I want my static method here to return a factory that creates and return Event<T> object. How can I fix this?
import com.lmax.disruptor.EventFactory;
public final class Event<T> {
private T event;
public T getEvent() {
return event;
}
public void setEvent(final T event) {
this.event = event;
}
public final static EventFactory<Event<T>> EVENT_FACTORY = new EventFactory<Event<T>>() {
public Event<T> newInstance() {
return new Event<T>();
}
};
}
Generic parameters of a class do not apply to static members.
The obvious solution is to use a method rather than a variable.
public static <U> EventFactory<Event<U>> factory() {
return new EventFactory<Event<U>>() {
public Event<U> newInstance() {
return new Event<U>();
}
};
}
The syntax is more concise in the current version of Java.
It is possible to use a the same instance of EventFactory stored in a static field, but that requires an unsafe cast.
You have:
public final class Event<T> {
...
public final static EventFactory<Event<T>> EVENT_FACTORY = ...
}
You cannot do this. T is a type that is associated with a specific instance of an Event<T>, and you cannot use it in a static context.
It's hard to give you good alternate options without knowing more about what exactly you are trying to do, as this is sort of an odd-looking factory implementation. I suppose you could do something like (put it in a method instead):
public final class Event<T> {
...
public static <U> EventFactory<Event<U>> createEventFactory () {
return new EventFactory<Event<U>>() {
public Event<U> newInstance() {
return new Event<U>();
}
};
};
}
And invoke it like:
EventFactory<Event<Integer>> factory = Event.<Integer>createEventFactory();
Or, if you don't want to be explicit (you don't really need to be, here):
EventFactory<Event<Integer>> factory = Event.createEventFactory();
Why don't you get rid of the whole static member of Event thing and either keep the factories separate, e.g.:
public final class GenericEventFactory<T> extends EventFactory<Event<T>> {
#Override public Event<T> newInstance() {
return new Event<T>();
}
}
And use, e.g., new GenericEventFactory<Integer>() where appropriate?

Categories

Resources