Structuralization Involving String Splitting

Question

For all subclasses that start with ~ I want to separate them into 2 values and join them to tail of an Array variable called "attributes". For example:

 

~ public void visitMethod(org.apache.bcel.classfile.Method arg0): 4

 

SUB_NAME =public void visitMethod(org.apache.bcel.classfile.Method arg0)

CC=4

Which I want to join to tail of an Array variable called "attributes":

String SUB_NAME = metadata[20];

int CC =Integer.parseInt(metadata[19]);

This is the text file I am parsing

 

gr.spinellis.ckjm.ClassVisitor 13 2 0 14 74 34 2 14 9 0.6042 431 0.8750 1 0.7273 0.2404 0 0 31.5385

 ~ public void visitMethod(org.apache.bcel.classfile.Method arg0): 4

 ~ public void registerCoupling(String arg0): 4

 ~ public void end(): 5

 ~ public void <init>(org.apache.bcel.classfile.JavaClass arg0, gr.spinellis.ckjm.ClassMetricsContainer arg1): 1

 ~ public gr.spinellis.ckjm.ClassMetrics getMetrics(): 1

 ~ private void incRFC(String arg0, String arg1, org.apache.bcel.generic.Type[] arg2): 1

 ~ public void start(): 1

 ~ void registerMethodInvocation(String arg0, String arg1, org.apache.bcel.generic.Type[] arg2): 1

 ~ public void visitField(org.apache.bcel.classfile.Field arg0): 1

 ~ public void visitJavaClass(org.apache.bcel.classfile.JavaClass arg0): 5

 ~ void registerFieldAccess(String arg0, String arg1): 2

 ~ static String className(org.apache.bcel.generic.Type arg0): 3

 ~ public void registerCoupling(org.apache.bcel.generic.Type arg0): 1

 

gr.spinellis.ckjm.ClassMetricsContainer 3 1 0 4 18 0 2 3 2 0.0000 66 1.0000 0 0.0000 0.5556 0 0 20.6667

 ~ void <init>(): 1

 ~ public gr.spinellis.ckjm.ClassMetrics getMetrics(String arg0): 2

 ~ public void printMetrics(gr.spinellis.ckjm.CkjmOutputHandler arg0): 3

 

gr.spinellis.ckjm.MetricsFilter 7 1 0 6 30 11 2 6 5 0.6667 218 1.0000 0 0.0000 0.2000 0 0 29.8571

 ~ public static boolean isJdkIncluded(): 1

 ~ static void processClass(gr.spinellis.ckjm.ClassMetricsContainer arg0, String arg1): 3

 ~ public static void runMetrics(String[] arg0, gr.spinellis.ckjm.CkjmOutputHandler arg1): 2

 ~ public static boolean includeAll(): 2

 ~ static void <clinit>(): 1

 ~ public static void main(String[] arg0): 7

 ~ public void <init>(): 1

 

gr.spinellis.ckjm.PrintPlainResults 2 1 0 3 8 0 1 2 2 0.0000 24 1.0000 0 0.0000 0.6250 0 0 10.5000

 ~ public void handleClass(String arg0, gr.spinellis.ckjm.ClassMetrics arg1): 1

 ~ public void <init>(java.io.PrintStream arg0): 1

 

gr.spinellis.ckjm.MethodVisitor 11 2 0 21 40 0 1 21 8 0.5500 209 1.0000 1 0.9474 0.1736 0 0 17.6364

 ~ public void visitINSTANCEOF(org.apache.bcel.generic.INSTANCEOF arg0): 1

 ~ public void visitLocalVariableInstruction(org.apache.bcel.generic.LocalVariableInstruction arg0): 2

 ~ public void visitCHECKCAST(org.apache.bcel.generic.CHECKCAST arg0): 1

 ~ private boolean visitInstruction(org.apache.bcel.generic.Instruction arg0): 4

 ~ public void visitInvokeInstruction(org.apache.bcel.generic.InvokeInstruction arg0): 2

 ~ public void visitReturnInstruction(org.apache.bcel.generic.ReturnInstruction arg0): 1

 ~ public void visitArrayInstruction(org.apache.bcel.generic.ArrayInstruction arg0): 1

 ~ public void visitFieldInstruction(org.apache.bcel.generic.FieldInstruction arg0): 1

 ~ void <init>(org.apache.bcel.generic.MethodGen arg0, gr.spinellis.ckjm.ClassVisitor arg1): 1

 ~ public void start(): 5

 ~ private void updateExceptionHandlers(): 3

 

gr.spinellis.ckjm.CkjmOutputHandler 1 1 0 4 1 0 3 1 1 2.0000 1 0.0000 0 0.0000 1.0000 0 0 0.0000

 

This is my passing logic of code:

 

  public List<Metrics> readMetricFromCSV(String fileName) {

 

    List<Metrics> metricsss = new ArrayList<>();

 

    Path pathToFile = Paths.get(fileName);

    // create an instance of BufferedReader

    // using try with resource, Java 7 feature to close resources

    try (BufferedReader br = Files.newBufferedReader(pathToFile,

    StandardCharsets.US_ASCII)) {

    // read the first line from the text file

    String line = br.readLine();

    while (line != null && !line.isEmpty()) { // loop until all lines

                                                    // are read

    String[] attributes = line.split(" "); // the file, using a  comma as the  delimiter first  18 values

 

    String str =  line;

 

    String[] arr1 = str.split("~");// the file, using a  comma as the  delimiter next  2 values

 

    String[] arr2 = arr1[1].split(":");

 

    String SUB_NAME = arr2[0], CC = arr2[1];

 

    //   System.out.println("SUB_NAME" + SUB_NAME + ", CC Value:" + CC);                             

 

    Metrics valueOfMetric = createMetric(attributes+SUB_NAME+CC);

 

    metricsss.add(valueOfMetric); // adding metric into ArrayList

 

    br.readLine();

    line = br.readLine();

        }

 

    } catch (IOException ioe) {

        ioe.printStackTrace();

}

 

Answer

Here’s what you want: Filter the file to get lines containing “~”, split each into two parts by “:”, remove “~” from the first part and name it SUB_NAME, and name the second part CC. It’s too complicated to code this in Java. But it’s simple to get it done in SPL (Structured Process Language):

A

1

=file("d:\\source.txt").import@si()

2

=A1.select(left(~,2)=="~")

3

=A2.(~.split@t(":"))

4

=A3.new(mid(~(1),3):SUB_NAME,~(2):CC)

A1: Import source.txt to as a single-field sequence of strings.

undefined

A2: Get members containing “~”.

undefined

A3: Split each of A2’s string members into a two-member sequence by the separator “:”.

undefined

A4: Generate a two-dimensional table made up of SUB_NAME field and CC field. Each value in SUB_NAME field is the first member of A3’s each sequence member with “~” deleted; CC field contains values that are the second members of A3’s sequence members.

undefined

An SPL script can easily integrated with Java. See How to Call an SPL Script in Java.