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 }