View Javadoc

1   package com.terradue.jcatalogue.client;
2   
3   /*
4    *    Copyright 2011-2012 Terradue srl
5    *
6    *    Licensed under the Apache License, Version 2.0 (the "License");
7    *    you may not use this file except in compliance with the License.
8    *    You may obtain a copy of the License at
9    *
10   *       http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *    Unless required by applicable law or agreed to in writing, software
13   *    distributed under the License is distributed on an "AS IS" BASIS,
14   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *    See the License for the specific language governing permissions and
16   *    limitations under the License.
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                  // ignore?!?
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          // check if there are missing parameters first
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 }