Does it make sense to have input parameters to a class? - java

I created a class of DocumentFilter type as follows:
public class CustomDocumentFilter extends DocumentFilter
{
private StyledDocument styledDocument;
private JTextPane panetxt;
public CustomDocumentFilter(JTextPane panetxt) {
this.panetxt = panetxt; // Not really necessary
this.styledDocument = panetxt.getStyledDocument();
}
private final StyleContext styleContext = StyleContext.getDefaultStyleContext();
Pattern pattern = buildPattern(mystring);
private Pattern buildPattern(String mystring)
{
StringBuilder sb = new StringBuilder();
String[] toke = StringUtils.split(mystring,",");
for (String token : toke) {
sb.append("\\b");
sb.append(token);
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
}
Pattern p = Pattern.compile(sb.toString());
return p;
}
My question is: how to include mystring within the call of CustomDocumentFilter?:
//String mystring="lalala";
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur));
EDIT:
Regarding the first way Jonathan suggests, I get this:
error: cannot find symbol Pattern pattern = buildPattern(mystring); ^ symbol: variable mystring location: class TextEditor.CustomDocumentFilter
I don't know if it has to do with the Pattern clause

Not 100% sure what is desired from the description. But I think your simply trying to ask how to get your local string value into your new CustomDocumentFilter object.
Well that is simple and you have choices! More than the two I show here.
first easy way is to add it to the constructor
public CustomDocumentFilter(JTextPane panetxt, String myString) {
...
pattern = buildPattern(mystring);
}
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur, myString));
another way is to use a method that returns the object
public CustomDocumentFilter myFunction(String myString) {
pattern = buildPattern(mystring);
return this;
}
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur).myFunction(myString));

Related

REGEX matcher any/all groups

while (matcher.find()) {
if (matcher.group(matcherGroup) != null) occurrence++;
}
return occurrence;
This is the code that i am using to search for the number of matches of a certain group. However there is no function like matcher.group(matcherGroup1, matcherGroup2) nor there is matcher.group(null) to search for multiple groups or all groups.
I have read Link groups (its stupid to group the arrays into one) or multiple groups?
Thanks
Can you not write your own matcherGroup implementation? The link you have provided is c#.
I have written a simple Java implementation which takes a single string, and then matches it against multiple RegExp patterns. The number of matches are then returned.
Alternatively please explain in more detail what you are trying to do.
package com.chocksaway;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
class SingleMatcher {
private Pattern pattern;
private java.util.regex.Matcher matcher;
private boolean found;
SingleMatcher(String input, String inputPattern) {
pattern = Pattern.compile(inputPattern);
matcher = pattern.matcher(input);
if (matcher.find()) {
this.found = true;
}
}
boolean getFound() {
return this.found;
}
}
class MatcherGroup {
private int matchedOccurances;
MatcherGroup(String input, List<String> multipleInputPattern) {
for (String inputPattern : multipleInputPattern) {
SingleMatcher eachSingleMatcher = new SingleMatcher(input, inputPattern);
if (eachSingleMatcher.getFound()) {
matchedOccurances++;
}
}
}
int getMatchedOccurances() {
return this.matchedOccurances;
}
}
/**
* Author milesd on 28/05/2017.
*/
public class RegExpMatcher {
public static void main(String[] args) {
SingleMatcher singleMatcher = new SingleMatcher("123", "\\d\\d\\d");
System.out.println(singleMatcher.getFound());
List<String> inputPatternList = new ArrayList<String>();
inputPatternList.add("\\d\\d\\d");
inputPatternList.add("John");
MatcherGroup matcherGroup = new MatcherGroup("John", inputPatternList);
System.out.println(matcherGroup.getMatchedOccurances());
}
}

custom method to concat string vs not using that method

I have a code like this:
private static final String BR_TAG = "<br/>";
private ResourceBundle rb;
public String create(){
String result = addLine("some text");
result = addLine("some text");
result = addLine("some text");
....
}
public String addLine(String text){
return rb.getString(text) + BR_TAG;
}
This is my current code, but is it optimal? Maybe I shouldn't use separate method to add line to my result? I could to this like this without method addLine:
public String create(){
String result = rb.getString("some text") + BR_TAG;
result = rb.getString("some text") + BR_TAG;
result = rb.getString("some text") + BR_TAG;
....
}
Or I can think about third option with passing StringBuilder to my method:
public String create(){
StringBuilder sb = new StringBuilder();
addLine("some text", sb);
addLine("some text", sb);
....
}
public void addLine(String text, StringBuilder sb){
sb.append(rb.getString(text)).append(BR_TAG);
}
What do you think which option is the best?
Why not use another method?
IMO, neither is the best, in terms of the beauty of the code. But in terms of performance, the third is better because a StringBuilder takes less time than the + when used a lot of times.
To make your code look prettier, Maybe make use of the Builder Pattern?
public class LineBuilder {
private StringBuilder builder;
private static final String BR_TAG = "<br/>";
public LineBuilder() {
builder = new StringBuilder();
}
public LineBuilder addLine(String text) {
builder.append(text).append(BR_TAG);
return this;
}
public String build() {
return builder.toString();
}
}
You can also add other methods like addHeader or addStrong that adds in <h1> and <strong> tags.
And you can use it like this:
String result = new LineBuilder()
.addLine("Hello")
.addLine("World")
.addLine("Bye!")
.build();
That just looks better!

JavaParser only showing comment, not JavaDoc

Disclaimer: I am only a lowly trainee, so please forgive me if I made elementary mistakes :(
I am writing an automatic API generator, and the classes need JavaDoc as well as comments because some of the values the API contains shouldn't be written down in the JavaDoc (exampleResponse for example).
However, it seems that the comments above the individual Methods replace the Javadoc, so when I want to get the description from the JavaDoc (which i want to do so I don't have to write it again in the comments), I have a problem.
Using getJavadoc() always returns null. I also attempted to use getOrphanComments(), but it returned null. Did I misunderstand the documentation? I assumed if I wrote two comments above a method, the top one would move to orphanComments for that method.
Is there any way to work around this?
Let the MethodDeclaration object is method
than you can get java doc using
if( method.hasComment() && method.getComment() instanceof JavadocComment ){
JavadocComment javaDoc = (JavadocComment)method.getComment();
// now you can get the content using
String content = javaDoc.getContent();
}
For the following types:
public final String name;
public final String signature;
public final String returnType;
public final Type returnFullType; // com.github.javaparser.ast.type.Type
public final String body;
public final String[] modifiers;
public final String[] parameterNames;
public final String[] parameterTypes;
public final Type[] parameterFullTypes; // com.github.javaparser.ast.type.Type
public final String[] exceptions;
public final String jdComment;
public final MethodDeclaration nativeJP_API_reference; // com.github.javaparser.ast.body.MethodDeclaration
This is a constructor for a class Method of my own concoction:
Method (MethodDeclaration md)
{
NodeList<Modifier> ml = md.getModifiers();
NodeList<Parameter> pl = md.getParameters();
NodeList<ReferenceType> te = md.getThrownExceptions();
this.nativeJP_API_reference = md;
this.name = md.getNameAsString();
this.signature = md.getDeclarationAsString();
this.returnType = md.getType().toString();
this.returnFullType = md.getType();
this.body = md.getBody().isPresent() ? md.getBody().get().toString() : null; // In ConstructorDeclaration, this is an Optional<BlockStmt>, not here!
this.modifiers = new String[ml.size()];
this.parameterNames = new String[pl.size()];
this.parameterTypes = new String[pl.size()];
this.parameterFullTypes = new com.github.javaparser.ast.type.Type[pl.size()];
this.exceptions = new String[te.size()];
this.jdComment = md.hasJavaDocComment() ? md.getJavadocComment().get().toString() : null;
int i = 0;
for (Parameter p : pl)
{
parameterNames[i] = p.getName().toString();
parameterTypes[i] = p.getType().toString();
parameterFullTypes[i] = p.getType();
i++;
}
i = 0;
for (Modifier m : ml) modifiers[i++] = m.toString();
i = 0;
for (ReferenceType r : te) exceptions[i++] = r.toString();;
}

Java, Passing parameters from one class to other class

I want to keep all validation methods (phone number validation, numeric validation) in a separate class and let the other classes to access validation methods commonly.How do I do this? Can someone assist me please.
class Validation {
public static boolean validateQty(String txt) {
String regx = "^0([1-9]){2}([0-9]){7}$";
Pattern compile = Pattern.compile(regx, Pattern.CASE_INSENSITIVE);
Matcher matcher = compile.matcher(txt);
return matcher.find();
}
public static boolean validateLetters(String txt) {
String regx = "[a-zA-Z]+\\.?";
Pattern pattern = Pattern.compile(regx, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(txt);
return matcher.find();
}
}
class ItemDetails {
private void addItem() {
boolean b = validateLetters(txtItemName.getText()); // I want to pass txtItemName value to Class Validation's validateLetters()
boolean c = validateQty(txtQty.getText());
}
}
Since these are static methods, you can call them by prefixing the class name:
boolean b = Validation.validateLetters(txtItemName.getText());
boolean c = Validation.validateQty(txtQty.getText());
You might also find it useful to pass the entire item to a single validate() method.
As these are static methods you can access like this
boolean b = Validation .validateLetters(txtItemName.getText());
boolean c = Validation .validateQty(txtQty.getText());
or create an object of Validation
Validation v=new Validation ();
boolean b = v .validateLetters(txtItemName.getText());
boolean c =v .validateQty(txtQty.getText());
boolean b = Validation .validateLetters(txtItemName.getText());
boolean c = Validation .validateQty(txtQty.getText());
Since your method in Validation class method validateLetters and validateQty is static you can call it this way . Otherwise you have to create instance of Validation first. Like
Validation v = new Validation();
boolean b = v.validateLetters(txtItemName.getText());
boolean c = v.validateQty(txtQty.getText());

Using a config/property file with variables

sI use a simple text-file like this
BMG-P (someLongComplicatedExpression)(.*P)
BMG T (someLongComplicatedExpression)(.*[Tt])
BMG MPA (someLongComplicatedExpression)(.*MPA)
to configure my application (Simple import with bufferedReader.readLine().split("\t")). What is bugging me is the redundance.
I am thinking about a solution like this:
%s=(someLongComplicatedExpression)
BMG-P %s(.*P)
BMG T %s(.*[Tt])
BMG MPA %s(.*MPA)
where I read the value of my variables (like %s), then replace their occurrences in the Strings after the import.
My questions are:
What alternative approaches do you know?
What is an easy way to implement the replacement of my variables in my code?
Can you point me to any frameworks that support property-files like that?
I wrote this simple extension to the Java Properties class:
import java.io.Serializable;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Allows properties to contain expansions of the form ${propertyName}. This
* class makes no attempt to detect circular references, so be careful.
*/
public class ExpandingProperties extends Properties implements PropertySource {
private static final long serialVersionUID = 259782782423517925L;
private final Expander expander = new Expander();
#Override
public String getProperty(String key) {
return expander.expand(super.getProperty(key), this);
}
}
class Expander implements Serializable {
private static final long serialVersionUID = -2229337918353092460L;
private final Pattern pattern = Pattern.compile("\\$\\{([^}]+)\\}");
/**
* Expands variables of the form "${variableName}" within the
* specified string, using the property source to lookup the
* relevant value.
*/
public String expand(final String s, final PropertySource propertySource) {
if (s == null) {
return null;
}
final StringBuffer sb = new StringBuffer();
final Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
final String variableName = matcher.group(1);
final String value = propertySource.getProperty(variableName);
if (value == null) {
throw new RuntimeException("No property found for: " + variableName);
}
matcher.appendReplacement(sb, value.replace("$", "\\$"));
}
matcher.appendTail(sb);
return sb.toString();
}
}
interface PropertySource {
String getProperty(String key);
}
Example usage:
public static void main(String[] args) {
Properties properties = new ExpandingProperties();
properties.put("myVar", "myLongExpression");
properties.put("foo", "${myVar}_1");
properties.put("bar", "${foo}_abc");
System.out.println(properties.getProperty("bar"));
}
Prints:
myLongExpression_1_abc
As ExpandingProperties is an extension of Properties it inherits all the load...() methods for loading values from property files.
An alternative is EProperties which does a similar thing to the above code, but goes even further and allows you to nest property files etc. I found it overkill for what I needed.

Categories