Use column as regex pattern with QueryDSL - java

I'm trying to use a column as a regular expression to match against a user provided string, but can't figure out how to do it with QueryDSL. Mostly I can't figure out how to put the user supplied string on the lefthand side of the expression.
Basically I'm looking to do something similar to the following, where ~ is my databases symbol for regex matching…
SELECT * FROM thing WHERE 'user supplied string' ~ thing.match

The following works
Expressions.predicate(Ops.MATCHES, Expressions.constant(...), path)

I don't know that this is the best way, but the only solution I was able to get working was to subclass StringExpression
class ConstantExpression extends StringExpression {
private Constant<String> constant;
static public ConstantExpression create(String constant) {
return new ConstantExpression(new ConstantImpl<String>(constant);
}
public ConstantExpression(Constant<String> mixin) {
super(mixin);
constant = mixin;
}
public <R,C> R accept(Visitor<R,C> v, C context) {
return v.visit(constnat, context);
}
}
Then I was able to use that as the lefthand side of the equation…
createJPAQueryFactory().from(qthing)
.where(ConstantExpression.create("user supplied…").like(thing.match)

Related

Find all Java methods using only one specific property of a specific type of parameter

We're in the process of trying to identify everywhere that a specific type of object is used only to get a specific property from it, and pass that property into the method instead.
I'm thinking IntelliJ IDEA's "Structural Search" might be a good tool for this, but I'm not sure how to formulate the search template.
A concrete example:
public class MyClass {
public Long getId() {...}
public void setSomethingElse(int se) {...}
}
public class SomeOtherClasses {
public void shouldBeMatched(MyClass mc) {
doSomething();
mc.getId();
doSomethingElse();
}
public void shouldNotBeMatched(MyClass mc) {
doSomething();
mc.getId();
mc.setSomethingElse(14);
doSomethingElse();
}
public void alsoShouldNotBeMatched(MyClass mc) {
shouldBeMatched(mc);
}
}
In the above example, if I'm looking for methods that only use getId, then I should find shouldBeMatched, but not be bothered with shoudNotBeMatched and alsoShouldNotBeMatched, because they do something with the mc object other than call getId().
I'm thinking IntelliJ IDEA's "Structural Search" might be a good tool for this
And it is indeed. The documentation can be tough though.
Let's check Search templates, filters, and script constraints page. It goes as follows.
Let's say, you have a variable that matches a method, a toString()
method. Then this variable is actually a PsiMethod node. Retrieving
variable.parent will produce a PsiClass node, and so forth.
variable.text then will give you the entire text of the method. If you
just need the name of the method, you can use variable.name.
It seems that the task can be done by choosing the right template and writing a corresponding Groovy script.
The template is called methods of the class and can be found under Existing templates. They provide __context__variable to be used with a script.
We have to be sure matched methods have parameters. It is simple enough, just put a count filter on a $Parameter$ variable.
Then we need to extract the name of a parameter of desired type and see if it is called in the body of the method. The following script will do.
def parameters = __context__.getParameterList().getParameters();
def parameter = parameters.find { p -> p.getType().getName().equals('MyClass') };
if (parameter == null) return false;
String parameterName = parameter.getName();
String methodText = __context__.getText();
String occurrence = "${parameterName}.";
String methodCall = "${parameterName}.getId()";
return methodText.count(occurrence) > 0 && methodText.count(occurrence) == methodText.count(methodCall);
Put it in the $Method$ variable filter and verify the results.

How to extract a String from a changing template in Java?

I have a question regarding best practices considering Java regular expressions/Strings manipulation.
I have a changing String template, let's say this time it looks like this:
/get/{id}/person
I have another String that matches this pattern eg.
/get/1234ewq/person
Keep in mind that the pattern could change anytime, slashes could disappear etc.
I would like to extract the difference between the two of them i.e. the result of the processing would be 1234ewq.
I know I could iterate over them char by char and compare, but, if it is possible, I wanted to find some smart approach to it with regular expressions.
What would be the best Java approach?
Thank you.
For you to answer your question with a regex approach I built a small example class which should hint you into a direction you could go with this (see below).
The problem with this approach is that you dynamically create a regular expression that depends on your template strings. This means that you have to somehow verify that your templates do not interfere with the regex compilation and matching process itself.
Also atm if you would use the same placeholder multiple times within a template the resulting HashMap only contains the value for the last placeholder mapping of that kind.
Normally this is the expected behaviour but this depends on your strategy of filling your templates.
For template processing in general you could have a look at the mustache library.
Also as Uli Sotschok mentioned, you probably would be better of with using something like google-diff-match-patch.
public class StringExtractionFromTemplate {
public static void main(String[] args) {
String template = "/get/{id}/person";
String filledTemplate = "/get/1234ewq/person";
System.out.println(diffTemplateInsertion(template, filledTemplate).get("id"));
}
private static HashMap<String, String> diffTemplateInsertion(String template, String filledTemplate){
//language=RegExp
String placeHolderPattern = "\\{(.+)}";
HashMap<String, String> templateTranslation = new HashMap<>();
String regexedTemplate = template.replaceAll(placeHolderPattern, "(.+)");
Pattern pattern = Pattern.compile(regexedTemplate);
Matcher templateMatcher = pattern.matcher(template);
Matcher filledTemplateMatcher = pattern.matcher(filledTemplate);
while (templateMatcher.find() && filledTemplateMatcher.find()) {
if(templateMatcher.groupCount() == filledTemplateMatcher.groupCount()){
for (int i = 1; i <= templateMatcher.groupCount(); i++) {
templateTranslation.put(
templateMatcher.group(i).replaceAll(placeHolderPattern,"$1"),
filledTemplateMatcher.group(i)
);
}
}
}
return templateTranslation;
}
}

I want to implement this format 12345-1234567-1 in regular expression in java

I want to implement a pakistan's standard format of cnic number which is like this:12345-1234567-1.
But I don't know anything about this. I found the following code for this purpose but it also giving errors in NetBeans.
private void idSearchKeyPressed(java.awt.event.KeyEvent evt) {
String cnicValidator = idSearch.getText();
if (cnicValidator.matches("^[0-9+]{5}-[0-9+]{7}-[0-9]{1}$")) {
idSearch.setEditable(true);
}
else {
idSearch.setEditable(false);
}
}
The pattern is correct. But it can be condensed to this:
^[\\d]{5}-[\\d]{7}-\\d$
Where does idSearch come from? If its not a final member of the class you can't access it in that way. So make sure idSearch is available inside idSearchKeyPressed. Also make sure that there are no trailing spaces or something like that. You can do this by calling
cnicValidator = cnicValidator.trim();
The following example returns true for both regex versions.
public static void main(String... args){
String id = "35241-7236284-4";
System.out.println(id.matches("^[\\d]{5}-[\\d]{7}-\\d$"));
System.out.println(id.matches("^[0-9+]{5}-[0-9+]{7}-[0-9]{1}$"));
}

How to create constant numeric value expression in QueryDSL?

I'd like to create query like this with QueryDSL
update WorkMessage w set w.totalPrice = 0.12 - w.totalCost;
I tried like this
Expression<Float> priceExpr = Expressions.constant(0.12f);
new JPAUpdateClause(em, w)
.set(w.totalPrice , priceExpr.subtract(w.totalCost));
But this doesn't work - Expression doesn't have subtract method.
I did it like this:
new JPAUpdateClause(em, w)
.set(w.totalPrice , w.totalCost.subtract(0.12f).negate());
but I'd like to know how to do it the first way.
//EDit
The second way don't work:
JPAUpdateClause.toString says:
update WorkMessage workMessage
set workMessage.totalPrice = -(workMessage.totalCost - :a1)
but the SQL result is
update work_message set total_price=-total_cost-?
Parentheses just dissapeared. Am I doing something wrong? It looks like theese:
w.totalCost.subtract(0.12f).negate()
w.totalCost.negate().subtract(0.12f)
have the same result.
For the above problem
w.totalCost.negate().add(0.12f)
works. But I think there is a bug.
We removed the DSL Constant types some time ago from Querydsl. If you really want to write it the first way, then you have to express it like this :
Expressions.operation(Float.class, Ops.SUB,
Expressions.constant(0.12f), w.totalCost)
or
NumberOperation.create(Float.class, Ops.SUB,
Expressions.constant(0.12f), w.totalCost)
if you need a NumberExpression
I had the same problem some time ago (needed the constant 0), and did build my own ConstantNumberExpression class. It turned out surprisingly easy :-)
A collegue just had the same problem, for the constant 1, so I decided to post it here.
private static class ConstantNumberExpression extends NumberExpression<Integer> {
private static final long serialVersionUID = 1220768215234001828L;
public ConstantNumberExpression(final int constant) {
super(new ConstantImpl<>(constant));
}
#Override
#Nullable
public <R, C> R accept(final Visitor<R, C> v, #Nullable final C context) {
return v.visit((Constant<Integer>) mixin, context);
}
}
Of course this could be done a bit more generic, using a type parameter, but we did need it only for Integer (actually only for zero and one).

How to convert NFA/DFA to java?

I have a scenario where I have designed the NFA and using JFLAP I have converted it to DFA.
I need to know, how to code it in Java?
Basically how to implement those state transitions in Java. I have seen some examples which do this using switch and if statements, but I can't see any relation to DFA/NFA design and how to use it to implement in Java.
if you want to use a more object oriented design over while(true)switch(state){...}
public class State{
private Map<Character,State> transitions=new HashMap<Character,State>();
public void addTransition(char ch,State st){
transitions.put(ch,st);
}
public State next(char ch){
return transitions.get(ch);
}
private boolean fin=false;
public boolean isFinal(){return fin;}
public boolean setFinal(boolean f){fin=f;}
}
and then the loop will be
State currState=startState;
while(currState!=null && input.hasNextChar()){//you can also end directly when final state is reached
char next = input.nextChar();//get next character
currState = currState.next(next);
}
if(currState!=null && currState.isFinal()){
// reached final state
}else{
// to bad didn't match
}
Take a look at dk.brics.automaton:
This Java package contains a DFA/NFA (finite-state automata) implementation with Unicode alphabet (UTF16) and support for the standard regular expression operations (concatenation, union, Kleene star) and a number of non-standard ones (intersection, complement, etc.)
Although you would have implemented it by now but there is very good implementation which is easy to digest. Use Digraph to maintain the epsilon transitions and stack to keep track of expressions. Check out this link from RS NFA.java .

Categories