I have an object that I want to serialize using Protocol Buffers and store in redis. The object contains a java.util.regex.Pattern that is complied when the object is instantiated.
public class SerializableEntity {
private Pattern pattern;
private List<String> options;
}
This pattern is used to validate inputs to a certain api. Since compiling the pattern each time is expensive, I'm compiling the pattern once during instantiation and then reusing the same pattern instance each time the api is invoked. How do I serialize this compile Pattern field in the following schema so I when I de-serialize the object, I can use it without compiling the pattern again?
message SerializableEntityProto {
repeated string option = 1;
// compiled pattern
}
Thanks.
java.util.regex.Pattern does not have encode and decode proto functions implemented in itself. However, you can implement that yourself pretty easy (as Andy Turner suggests). Something like this:
Proto
syntax = "proto2";
package termin4t0r;
option java_package = "com.example.termin4t0r";
// Proto for java.util.regex.Pattern
message RegexPatternProto {
// See Pattern.pattern()
optional string pattern = 1;
// See Pattern.flags()
optional int64 flags = 2;
}
Java encode and decode functions
class RegexpPatternProtos {
public static RegexPatternProto encode(java.util.regex.Pattern pattern) {
return RegexPatternProto.newBuilder()
.setPattern(pattern.pattern())
.setFlags(pattern.flags())
.build();
}
public static java.util.regex.Pattern decode(RegexPatternProto patternProto) {
return new RegexPatternProto(
patternProto.getPattern(), patternProto.getFlags());
}
}
I leave the unittests as an exercise :) I even find serializing this way preferable as protocol buffers have forward and backward compatibility, whereas java serialization has problems with that.
I think this is a case of square peg and round hole, protobuf and serialization is not meant to be used that way.
Anyway it seems like you initialize a regex with every API call. I don't know how your app decides which Regex to use for a particular API, but you must start out with a Regex string to compile.
Instead of trying to serializing the pattern, store it in memory in a HashMap<String,Pattern>( Regex string as a key and the compiled pattern as value). And then get the pattern when you need it.
Related
ArgumentMatchers.matches( String regex ) exists... and it is possible to devise regexes which don't match a given String. But it is far from trivial (several threads in SO).
Is it wrong of me (or wrong-headed) to think it might be a nice idea to request the Mockito designers to take the heavy-lifting out of this and add it as a feature? It just seems that, in the context of mocking and so forth, it is a far-from-exceptional use case...
PS also, I'm not clear with ArgumentMatchers.matches how you go about saying "this may be a multiline String we're matching against, don't worry about it"... wouldn't it be better to have a Pattern rather than a simple String?
later
Feature request "enhanced" at Mockito HQ (on Github). "bric3" there says one should use Jeff Bowman's technique for "does not match". But she/he seems to think the Pattern idea is worth thinking about.
Re not(): Mockito's own documentation says "Use additional matchers very judiciously because they may impact readability of a test. It is recommended to use matchers from Matchers and keep stubbing and verification simple."
Also I find I must "possible dupe" my own question: How to write a matcher that is not equal to something. Searching with hindsight is always easier...!
later still
Many thanks to Brice for adding this so quickly. Updated my gradle.build and... new 4.1 core downloaded from Maven Central and immediately available for use.
No need for a request: You can compose what you want using AdditionalMatchers.not.
when(yourComponent.acceptString(not(matches("foo|ba[rz]"))))
.thenThrow(new IllegalArgumentException());
If you want to match a Pattern, you might need to write your own ArgumentMatcher subclass, but it's quite easy from there:
public class MatchesPattern implements ArgumentMatcher<String> {
private final Pattern pattern;
public MatchesPattern(Pattern pattern) { this.pattern = pattern; }
#Override public boolean matches(String string) {
return pattern.matcher(string).matches();
}
#Override public String toString() {
return "[string matching /" + pattern.toString() + "/]";
}
/** Optional. */
public static MatchesPattern matchesPattern(Pattern pattern) {
return new MatchesPattern(pattern);
}
}
You can then consume that class using:
when(yourComponent.acceptString(not(argThat(new MatchesPattern(yourPattern)))
.thenThrow(new IllegalArgumentException());
// or with the static factory method:
when(yourComponent.acceptString(not(argThat(matchesPattern(yourPattern)))
.thenThrow(new IllegalArgumentException());
For future readers, Mockito 2.4.1 has been released with support of the Pattern class :
Now you should be abble to write :
when(yourComponent.acceptString(not(matches(Pattern.compile(...)))
.thenThrow(new IllegalArgumentException());
I'm working on a project needing a .NET program and a JAVA program to interoperate via protocol.
The JAVA side uses Jackson to serialize simple JAVA objects (resulting in JSON-Packets having the concrete class as #class members).
But the .NET side uses different conventions for this - here the type is specified by __type members.
Can I massage the .NET side to accept JACKSON formatted packets? Changing the protocol format on the JAVA side would be suboptimal, because the protocol is already used elsewhere, so getting .NET to adapt would be preferred.
Currently I was looking at the .NET DataContractJsonSerializer - but it is also possible to employ a third party library on the .NET side if required.
Can JSON.NET offer this kind of flexibility? BTW, problems like assembly versions are not an issue here, so it is perfectly OK for the protocol to not send that information.
EDIT to make my intentions clearer, here some example code:
JAVA side
package some.pkg;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
#JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)public abstract class EventBase {
public final String superField;
protected EventBase(final String superField) {
this.superField = superField;
}
}
A second JAVA package class
package some.pkg;
public final class EventA extends EventBase {
public final int intFieldA;
public EventA(final int intFieldA, final String superField) {
super(superField);
this.intFieldA = intFieldA;
}
private EventA() {this(0,null);}//for jackson
}
JSON generated by Jackson
A JSON string generated by Jackson will look e.g. like
{
"#class" : "some.pkg.EventA",
"superField" : "S1",
"intFieldA" : 1
}
.NET
Here I have equivalent classes (with methods not shown here - this is a request/event protocol, and the request methods are stored in the packets themselves.
So here I expect something akin to
namespace some.pkg
{
public sealed class EventA extends EventBase {
public EventA(final int intFieldA, final String superField) : base(superField) {
this.intFieldA=intFieldA;
}
[DataMember]
public int fieldA { get; private set; }
}
... superclass and other subclasses of EventBase elied.
The problem here for me is Jackson's way of signaling the class, either via #c or via #class, versus Microsoft's standart "__type" attribute, or JSON.NET's "$type".
Edited - Summary
OK, the answer with switching $type versus #class before resp. after the .NET serializer does it's deed works rather nicely (as long as the magical Strings #class and $type are not used elsewhere as payload data).
A look into JSON.NET's sources showed me that the $type descriminator field is a const string, so changing that would require us to use a patched JSON.NET library, which looks to be more work than just changing the offending strings before resp. after the JsonReader/Writer classes do their deed.
I am not so sure about converting default naming conventions of JSON.NET. But if I were you, I would use a "JSON interceptor" function like the following
public static class JSONInterceptor {
public static string sanitizeJSON(string originalJSONFromJava)
{
//add any other validation checks here as you may see fit. ex: null checks
return originalJSONFromJava.replace("#class", "$type");
}
}
and then use it to generate the .NET class like the following
return JsonConvert.DeserializeObject<EventA>(JSONInterceptor.sanitizeJSON(originalJSONFromJava));
I haven't tried this myself yet. but the idea is to show you that this could be done in the following way, too
JSON is a data format and is equal to all languages, even if you use Tex to generate json data.
In .net the easiest (imho) way for deserializing json object is using Json.Net.
Example:
Java side
public class A {
#JsonProperty("afield")
public String afield;
}
Then declare an equal class in C#
public class A {
[JsonProperty("afield")]
public string afield {get;set;}
}
So when you receive the json object A from java side you only just need call JsonConvert.DeserializeObject<A>(stringreceived) to get the object.
There is a kind of equivalent of the Jackson annotion for C# that works with JSON.net and JsonSubTypes:
[JsonConverter(typeof(JsonSubtypes), "#class")]
[JsonSubtypes.KnownSubType(typeof(EventA), "some.pkg.EventA")]
public class EventBase {
}
see more possibilites in the readme
I need to be able to turn a list of Spring MVC URL pattern matching expressions into actual Regex Patterns so I can match strings against them.
Example Spring pattern :
/actionGroups/{action-group-id:\d+}
At the moment if I compile the above string I get a PatternSyntaxException because of illegal repetition due to the { characters.
Does Spring expose the mechanism it uses to compile/match these string into actual Regex Patterns? It would be cool if I could reuse their functionality.
Else I suppose I'd need to escape the { characters manually and strip out the pattern name.. action-group-id in this example.
There is nothing wrong with what you are trying to do, check your pattern syntax :
#RequestMapping("/actionGroups/{action-group-id:\\d+}")
public void test(#PathVariable(value = "action-group-id") Integer id) {
// you can use id ...
}
Looks like it was the AntPathMatcher class i was looking for as per Sotirios Delimanolis's comment above.
This class has a matches method which takes a URL Pattern like the one above and an URL string and returns true/false depending on if the string matches.
Is it possible to use RestEasy's Path annotation to get the following string:
/items.json
I was thinking something like this: /items{(\.)?format}, where format could be json, xml etc.
I would then have a method with an argument like: #PathParam("format") String format.
Thanks.
I managed to make the following work with my use case: item{format:(\.(json|xml))?}
I chose to make the reg exp restrictive so as not to have to handle unsupported or invalid formats inside the actual service method, but if one prefers a more general approach I think that instead of (json|xml) one can add \S+.
you might want to create two methods, one for the default type and one for the optional types but yes, your logic should work:
#Path(items.{format})
public Response getItems(#PathParam("format") String format) {
}
#Path(items)
public Response getItems() {
return getItems("json");
}
Say I follow the Single Responsibility Principle and I have the following classes.
public class Extractor {
public Container extract(List<Container> list) {
... some extraction
}
}
public class Converter {
public String convert(Container container) {
... some conversion
}
}
As you can see it's following the principle and all the names of the classes/methods tell what they do. Now I have another class that has a method like this.
public class SomeClass {
private Extractor extractor = new Extractor();
private Converter converter = new Converter();
private Queue queue = new Queue();
public void someMethod(List<Container> list) {
Container tmp = extractor.extract(list);
String result = converter.convert(tmp);
queue.add(result);
}
}
As you can see the "someMethod"-Method does call extract, convert and add. My question is now, how do you call such a class/method? It's not actually extracting, converting or adding but it's calling those?
If you name the method after its responsibility what would that be?
Well since you seem to add to a queue and you don't return anything I'd call it addToQueue. The fact that you convert + extract is implementation detail that I don't think needs to be exposed.
What about processAndQueueMessage?
Also (not related), you shouldn't create (using new) the Extractor and Converter in your SomeClass, you should rather inject them (at construction or in setters), and use interfaces to them. That will make it easier to test, and reduce coupling between implementations.
// Assuming Converter and Extractor are interfaces to the actual implementations
public class SomeClass {
private final Extractor extractor ;
private final Converter converter;
private Queue queue = new Queue();
public SomeClass(Extractor extractor, Converter converter) {
this.converter = converter;
this.extractor = extractor;
}
public void someMethod(List<Container> list) {
Container tmp = extractor.extract(list);
String result = converter.convert(tmp);
queue.add(result);
}
}
And you create it using:
final SomeClass myProcessor = new SomeClass(new MyExtractorImplementation(), new MyConverterImplementation());
(Or use a DI container, like Spring or Pico)
What you do is think about the composite meaning of the sequence of method calls, turn that into a concise verb or verb phrase and use that as the name. If you can't come up with a concise name then you could use a generic / neutral name (like "process") or use something completely bogus (like "sploddify").
If you want the name to be really generic, I'd go with addToQueue() or populateQueue() since getting something into that object seems to be the point of the method.
But really at that level I'd call it by what business logic it's trying to accomplish, in which case the name really depends on what it's being used for.
If you can't come up with a good name, it is an indication that your procedural abstraction is rather arbitrary / artificial, and a possible hint that there might be a better way to do it. Or maybe not.
Sounds like some kind of builder class. You get data in one format, convert it and then create some kind of output format. So how about "SomethingSomethingBuilder"?
I'm assuming someone downvoted me because I forgot to provide a good name for the method. Sorry about that.
So this method adds incrementally data into your builder class. I would call it, "Add", "AddData" or "Push" (I'd probably go with push because that has very similar meaning in many standard classes).
Alternative to "Builder" could potentially be "SomeKindOfCreator". Obviously you would name it based on whatever it is your class is actually creating.