...
- I removed the "getLister" method as I haven't seen any protocol or use-case where this actually made sense.
- I added the prefix "Plc" to the Query as I did notice, that when working with other sources or destinations the class Query/Address is a little vague and I did have to specify some "Address" types with their full package name due to Class name collisions at least once
- I changed the "parse" to "prepare" as it sort of correlates to the "prepareStatement" of JDBC ... and some times I could imagine, that more work is involved than simple parsing of a string (For Beckhoff ADS and EtherNet/IP this method could actively connect to the corresponding resource so in future read operations only the connection-id has to be provided)
| Code Block |
|---|
|
package org.apache.plc4x.java.api.model;
/**
* Base type for all query types.
* Typically every driver provides an implementation of this interface in order
* to be able to describe the query for a resource. As this is completely tied to
* the implemented protocol, this base interface makes absolutely no assumption to
* any information it should provide.
*
* In order to stay platform and protocol independent every driver connection implementation
* provides a prepareQuery(String) method that is able to parse a string representation of
* a query into it's individual query type. Manually constructing Query objects
* manually makes the solution less independent from the protocol, but might be faster.
*/
public interface PlcQuery {
} |
Notes to the above class:
- I still think there is no immediate need to define any fields or methods in this interface as I haven't seen any common ground yet. Even if we are currently adding "TYPE" information to most queries, in Modbus the type is directly tied to the address you are reading. So If you are reading a "Register" or a "Coil", the datatype is fixed.
| Code Block |
|---|
|
package org.apache.plc4x.java.api.messages;
import org.apache.plc4x.java.api.messages.items.RequestItem;
import java.util.*;
/**
* Base type for all messages sent from the plc4x system to a connected plc.
* @param <REQUEST_ITEM>
*/
public abstract class PlcRequest<REQUEST_ITEM extends RequestItem> implements PlcMessage {
protected final Map<String, REQUEST_ITEM> requestItemMap;
public PlcRequest() {
this.requestItemMap = new HashMap<>();
}
public PlcRequest(List<REQUEST_ITEM> requestItems) {
this();
Objects.requireNonNull(requestItems, "Request items must not be null");
// Add all the items to the internal map.
requestItems.stream().map(item -> requestItemMap.put(item.getName()));
}
public void addItem(REQUEST_ITEM requestItem) {
Objects.requireNonNull(requestItem, "Request item must not be null");
requestItemMap.put(requestItem.getName(), requestItem);
}
public REQUEST_ITEM getItem(String name) {
Objects.requireNonNull(name, "Name must not be null");
return requestItemMap.get(name);
}
public Collection<REQUEST_ITEM> getRequestItems() {
return requestItemMap.values();
}
public int getNumberOfItems() {
return getRequestItems().size();
}
public boolean isEmpty() {
return requestItemMap.isEmpty();
}
} |
Notes to the above class:
- I changed the list with a Map, so we can directly reference items.
- I removed the "single-item" methods.
- For clarity reasons, I stripped the boilerplate: toString, equals, hashCode methods
| Code Block |
|---|
|
package org.apache.plc4x.java.api.messages.items;
import org.apache.plc4x.java.api.model.PlcQuery;
import java.util.Objects;
/**
* Wrapper Object to bind a name to a {@link PlcQuery} .
*/
public abstract class PlcRequestItem {
private final String name;
private final PlcQuery query;
public RequestItem(String name, PlcQuery query) {
Objects.requireNonNull(name, "Name must not be null");
Objects.requireNonNull(query, "Query type must not be null");
this.name = name;
this.query = query;
}
public String getName() {
return null;
}
public PlcQuery getQuery() {
return query;
}
}
...
public class PlcReadRequestItem extends PlcRequestItem {
public RequestItem(String name, PlcQuery query) {
super(name, query);
}
} |
Notes to the above class:
- Added the "Plc" prefix to the classname.
- I removed the datatype both from the properties as well as the generic type as I think type information - if needed - should be inside the query object.
- For clarity reasons, I stripped the boilerplate: toString, equals, hashCode methods
- PlcReadRequestItem no longer has a "size", as that's part of the query now.
- NOTE: I would suggest to not remove PlcReadRequestItem, even if we could simply make PlcRequestItem non-abstract. For simplicity of the API I would opt for keeping it ... so we always have matching pairs of PlcXYZRequestItem and PlcXYZResponseItems.
| Code Block |
|---|
|
package org.apache.plc4x.java.api.messages.items;
import org.apache.plc4x.java.api.types.ResponseCode;
import java.util.Objects;
public abstract class PlcResponseItem {
private final PlcRequestItem requestItem;
private final ResponseCode responseCode;
public ResponseItem(PlcRequestItem requestItem, ResponseCode responseCode) {
Objects.requireNonNull(requestItem,"Request item must not be null");
Objects.requireNonNull(responseCode,"Response code must not be null");
this.requestItem = requestItem;
this.responseCode = responseCode;
}
public PlcRequestItem getRequestItem() {
return requestItem;
}
public ResponseCode getResponseCode() {
return responseCode;
}
} |
Notes to the above class:
- Added the "Plc" prefix to the classname.
- I removed the datatype both from the properties as well as the generic type as I think type information - if needed - should be inside the query object.
- For clarity reasons, I stripped the boilerplate: toString, equals, hashCode methods
Notes to the above class:
Notes to the above class:
Notes to the above class: