1 package com.terradue.jcatalogue.client;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import static java.lang.String.format;
20 import static java.util.regex.Pattern.compile;
21
22 import java.util.HashSet;
23 import java.util.Set;
24 import java.util.StringTokenizer;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import lombok.Data;
29 import lombok.EqualsAndHashCode;
30
31 @Data
32 @EqualsAndHashCode( callSuper = false )
33 public final class OpenSearchUrl
34 extends CatalogueEntity
35 {
36
37 private static final String APPLICATION_ATOM_XML = "application/atom+xml";
38
39 private static final String PARAM_DELIMITER = "&";
40
41 private static final String OPTIONAL_MARKER = "?";
42
43 private static final Pattern PARAM_VALUE_PATTERN = compile( "\\{(([\\w:_]+)(\\?)?)\\}" );
44
45 private final String type;
46
47 private final String baseUrl;
48
49 private final OpenSearchParameter[] parameters;
50
51 public OpenSearchUrl( final String type, final String template )
52 {
53 this.type = type;
54
55 int queryDelimiterIndex = template.indexOf( '?' );
56
57 baseUrl = template.substring( 0, queryDelimiterIndex );
58
59 StringTokenizer parametersTokenizer = new StringTokenizer( template.substring( queryDelimiterIndex + 1 ),
60 PARAM_DELIMITER );
61 parameters = new OpenSearchParameter[parametersTokenizer.countTokens()];
62 int index = 0;
63
64 while ( parametersTokenizer.hasMoreTokens() )
65 {
66 String parameter = parametersTokenizer.nextToken();
67 int parameterSeparatorIndex = parameter.indexOf( '=' );
68
69 String key = parameter.substring( 0, parameterSeparatorIndex );
70 String value = parameter.substring( parameterSeparatorIndex + 1 );
71
72 Matcher matcher = PARAM_VALUE_PATTERN.matcher( value );
73 if ( matcher.matches() )
74 {
75 boolean mandatory = ( 4 == matcher.groupCount() && OPTIONAL_MARKER.equals( matcher.group( 3 ) ) );
76 parameters[index] = new OpenSearchParameter( key, matcher.group( 2 ), mandatory );
77 }
78 else
79 {
80
81 }
82
83 index++;
84 }
85 }
86
87 public Catalogue invoke( Parameter...parameters )
88 {
89 if ( !APPLICATION_ATOM_XML.equals( type ) )
90 {
91 throw new IllegalStateException( "Direct URL invocation supports application/atom+xml only" );
92 }
93
94
95 Set<String> parametersName = new HashSet<String>();
96 for ( Parameter parameter : parameters )
97 {
98 parametersName.add( parameter.getName() );
99 }
100
101 for ( OpenSearchParameter searchParameter : this.parameters )
102 {
103 if ( searchParameter.isMandatory() && !parametersName.contains( searchParameter.getKey() ) )
104 {
105 throw new IllegalArgumentException( format( "Mandatory parameter %s not found!", searchParameter.getKey() ) );
106 }
107 }
108
109 return getCatalogueClient().getCatalogue( baseUrl, parameters );
110 }
111
112 }