package com.vtence.molecule.routing;

import com.vtence.molecule.Matcher;
import org.simpleframework.http.Path;
import org.simpleframework.http.parse.PathParser;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DynamicPath implements Matcher<String> {

    private final String pattern;

    public DynamicPath(String pattern) {
        this.pattern = pattern;
    }

    public boolean matches(String actual) {
        return sameLength(segments(pattern), segments(actual)) && match(segments(pattern), segments(actual));
    }

    private boolean match(String[] expectedSegments, String[] actualSegments) {
        for (int i = 0; i < expectedSegments.length; i++) {
            String expected = expectedSegments[i];
            String actual = actualSegments[i];
            if (!(expected.equals(actual) || isDynamic(expected))) return false;
        }
        return true;
    }

    private boolean sameLength(String[] expected, String[] actual) {
        return expected.length == actual.length;
    }

    private String[] segments(String path) {
        return removeEmptyParts(path.split("/"));
    }

    private String[] removeEmptyParts(String[] parts) {
        List<String> significantParts = new ArrayList<String>();
        for (String part : parts) {
            if (!part.isEmpty()) significantParts.add(part);
        }
        return significantParts.toArray(new String[significantParts.size()]);
    }

    private boolean isDynamic(String segment) {
        return segment.startsWith(":");
    }

    public Map<String, String> boundParameters(String path) {
        Path actual = new PathParser(path);
        Map<String, String> boundParameters = new HashMap<String, String>();

        String[] parts = segments(this.pattern);
        for (int i = 0; i < parts.length; i++) {
            String segment = parts[i];
            if (isDynamic(segment)) boundParameters.put(stripLeadingColonFrom(segment), actual.getSegments()[i]);
        }
        return boundParameters;
    }

    private String stripLeadingColonFrom(String segment) {
        return segment.substring(1);
    }
}

@@ -70,96 +70,8 @@
 her;
-%0Aimport org.simpleframework.http.Path;%0Aimport org.simpleframework.http.parse.PathParser;
 %0A%0Aim
@@ -241,22 +241,20 @@
 e final 
-String
+Path
  pattern
@@ -320,23 +320,33 @@
 ttern = 
+new Path(
 pattern
+)
 ;%0A    %7D%0A
@@ -402,107 +402,36 @@
     
-return sameLength(segments(pattern), segments(actual)) && match(segments(pattern), segments
+Path path = new Path
 (actual)
 );%0A 
@@ -430,906 +430,263 @@
 ual)
-)
 ;%0A    
-%7D%0A%0A
     
-private boolean match(String%5B%5D expectedSegments, String%5B%5D actualSegments) %7B%0A        for (int i = 0; i %3C expectedSegments.length; i++) %7B%0A            String expected = expectedSegments%5Bi%5D;%0A            String actual = actualSegments%5Bi%5D;%0A            if (!(expected.equals(actual) %7C%7C isDynamic(expected))) return false;%0A        %7D%0A        return true;%0A    %7D%0A%0A    private boolean sameLength(String%5B%5D expected, String%5B%5D actual) %7B%0A        return expected.length == actual.length;%0A    %7D%0A%0A    private String%5B%5D segments(String path) %7B%0A        return removeEmptyParts(path.split(%22/%22));%0A    %7D%0A%0A    private String%5B%5D removeEmptyParts(String%5B%5D parts) %7B%0A        List%3CString%3E significantParts = new ArrayList%3CString%3E();%0A        for (String part : parts) %7B%0A            if (!part.isEmpty()) significantParts.add(part);%0A        %7D%0A        return significantParts.toArray(new String%5BsignificantParts.size()%5D)
+if (!pattern.sameLengthAs(path)) return false;%0A%0A        for (int i = 0; i %3C pattern.segmentCount(); i++) %7B%0A            if (!isDynamic(pattern.segment(i)) && !pattern.segment(i).equals(path.segment(i))) return false;%0A        %7D%0A        return true
 ;%0A  
@@ -860,22 +860,17 @@
    Path 
-actual
+p
  = new P
@@ -876,14 +876,8 @@
 Path
-Parser
 (pat
@@ -962,57 +962,8 @@
 );%0A%0A
-        String%5B%5D parts = segments(this.pattern);%0A
     
@@ -992,18 +992,28 @@
 %3C pa
-rts.length
+ttern.segmentCount()
 ; i+
@@ -1052,14 +1052,24 @@
 = pa
-rts%5Bi%5D
+ttern.segment(i)
 ;%0A  
@@ -1101,16 +1101,34 @@
 egment))
+ %7B%0A               
  boundPa
@@ -1157,20 +1157,16 @@
 ingColon
-From
 (segment
@@ -1172,33 +1172,36 @@
 t), 
-actual.getSegments()%5Bi%5D);
+p.segment(i));%0A            %7D
 %0A   
@@ -1286,72 +1286,938 @@
 olon
-From(String segment) %7B%0A        return segment.substring(1);%0A    %7D%0A%7D%0A
+(String segment) %7B%0A        return segment.substring(1);%0A    %7D%0A%0A    public static class Path %7B%0A%0A        private final String path;%0A%0A        public Path(String path) %7B%0A            this.path = path;%0A        %7D%0A%0A        public String%5B%5D segments() %7B%0A            return removeEmptyParts(path.split(%22/%22));%0A        %7D%0A%0A        private static String%5B%5D removeEmptyParts(String%5B%5D parts) %7B%0A            List%3CString%3E segments = new ArrayList%3CString%3E();%0A            for (String part : parts) %7B%0A                if (!part.isEmpty()) segments.add(part);%0A            %7D%0A            return segments.toArray(new String%5Bsegments.size()%5D);%0A        %7D%0A%0A        public boolean sameLengthAs(Path other) %7B%0A            return other.segments().length == segments().length;%0A        %7D%0A%0A        public String segment(int index) %7B%0A            return segments()%5Bindex%5D;%0A        %7D%0A%0A        public int segmentCount() %7B%0A            return segments().length;%0A        %7D%0A    %7D%0A%7D

Make code parsing dynamic parameters independent of simpleweb and a bit cleaner