001 package com.khubla.pragmatach.framework.url;
002
003 import java.io.ByteArrayInputStream;
004 import java.io.InputStream;
005 import java.util.ArrayList;
006 import java.util.List;
007
008 import org.antlr.v4.runtime.ANTLRInputStream;
009 import org.antlr.v4.runtime.CommonTokenStream;
010
011 import com.khubla.pragmatach.framework.api.PragmatachException;
012 import com.khubla.pragmatach.framework.uri.antlr4.RouteSpecificationLexer;
013 import com.khubla.pragmatach.framework.uri.antlr4.RouteSpecificationParser;
014 import com.khubla.pragmatach.framework.uri.antlr4.RouteSpecificationParser.IdsegmentContext;
015 import com.khubla.pragmatach.framework.uri.antlr4.RouteSpecificationParser.PathsegmentContext;
016 import com.khubla.pragmatach.framework.uri.antlr4.RouteSpecificationParser.RoutespecificationContext;
017 import com.khubla.pragmatach.framework.uri.antlr4.RouteSpecificationParser.SegmentContext;
018
019 /**
020 * @author tome
021 */
022 public class RouteSpecification {
023 /**
024 * id fields
025 */
026 private final List<String> ids;
027 /**
028 * segments
029 */
030 private final List<RouteSpecificationSegment> segments;
031
032 /**
033 * ctor
034 */
035 public RouteSpecification(String uri) throws PragmatachException {
036 String fixedUri = uri;
037 if (false == uri.startsWith("/")) {
038 fixedUri = "/" + uri;
039 }
040 segments = parse(fixedUri);
041 if ((null != segments) && (segments.size() > 0)) {
042 ids = new ArrayList<String>();
043 for (final RouteSpecificationSegment routeSpecificationSegment : segments) {
044 if (null != routeSpecificationSegment.getVariableId()) {
045 ids.add(routeSpecificationSegment.getVariableId());
046 }
047 }
048 } else {
049 ids = null;
050 }
051 }
052
053 public List<String> getIds() {
054 return ids;
055 }
056
057 public List<RouteSpecificationSegment> getSegments() {
058 return segments;
059 }
060
061 /**
062 * parse an inputstream
063 */
064 private RoutespecificationContext parse(InputStream inputStream)
065 throws PragmatachException {
066 try {
067 if (null != inputStream) {
068 final RouteSpecificationLexer routeSpecificationLexer = new RouteSpecificationLexer(
069 new ANTLRInputStream(inputStream));
070 final CommonTokenStream tokens = new CommonTokenStream(
071 routeSpecificationLexer);
072 final RouteSpecificationParser routeSpecificationParser = new RouteSpecificationParser(
073 tokens);
074 return routeSpecificationParser.routespecification();
075 } else {
076 throw new IllegalArgumentException();
077 }
078 } catch (final Exception e) {
079 throw new PragmatachException("Exception in parse", e);
080 }
081 }
082
083 /**
084 * parse a URI into parts.
085 */
086 private List<RouteSpecificationSegment> parse(String uri)
087 throws PragmatachException {
088 try {
089 final List<RouteSpecificationSegment> ret = new ArrayList<RouteSpecificationSegment>();
090 /*
091 * special case for "/"
092 */
093 if (uri.compareTo("/") == 0) {
094 RouteSpecificationSegment routeSpecificationSegment = new RouteSpecificationSegment(
095 "/", null);
096 ret.add(routeSpecificationSegment);
097
098 } else {
099 final RoutespecificationContext routespecificationContext = parse(new ByteArrayInputStream(
100 uri.getBytes("UTF-8")));
101 for (SegmentContext segmentContext : routespecificationContext
102 .segment()) {
103 RouteSpecificationSegment routeSpecificationSegment = parseSegment(segmentContext);
104 ret.add(routeSpecificationSegment);
105 }
106 }
107
108 return ret;
109 } catch (final Exception e) {
110 throw new PragmatachException("Exception in parse", e);
111 }
112 }
113
114 private RouteSpecificationSegment parseSegment(SegmentContext segmentContext)
115 throws PragmatachException {
116 try {
117 PathsegmentContext pathsegmentContext = segmentContext.getChild(
118 PathsegmentContext.class, 0);
119
120 if (null != pathsegmentContext) {
121 return new RouteSpecificationSegment(
122 pathsegmentContext.getText(), null);
123 } else {
124 IdsegmentContext idsegmentContext = segmentContext.getChild(
125 IdsegmentContext.class, 0);
126 if (null != idsegmentContext) {
127 String id = idsegmentContext.getChild(1).getText();
128 return new RouteSpecificationSegment(null, id);
129 }
130 }
131 return null;
132
133 } catch (final Exception e) {
134 throw new PragmatachException("Exception in parseNode", e);
135 }
136 }
137 }