Esempio n. 1
0
 /**
  * Returns a list of saved queries
  *
  * @param criteria a multivalued map that has the filter criteria
  * @param start Displacement from the start of the search result
  * @param count Count of number of records required
  * @return list of saved queries
  * @throws LensException
  */
 public ListResponse getList(MultivaluedMap<String, String> criteria, long start, long count)
     throws LensException {
   final StringBuilder selectQueryBuilder =
       new StringBuilder("select * from " + SAVED_QUERY_TABLE_NAME);
   final Set<String> availableFilterKeys = FILTER_KEYS.keySet();
   final Sets.SetView<String> intersection =
       Sets.intersection(availableFilterKeys, criteria.keySet());
   if (intersection.size() > 0) {
     final StringBuilder whereClauseBuilder = new StringBuilder(" where ");
     final List<String> predicates = Lists.newArrayList();
     for (String colName : intersection) {
       predicates.add(
           FILTER_KEYS.get(colName).resolveFilterExpression(colName, criteria.getFirst(colName)));
     }
     Joiner.on(" and ").skipNulls().appendTo(whereClauseBuilder, predicates);
     selectQueryBuilder.append(whereClauseBuilder.toString());
   }
   final String listCountQuery =
       "select count(*) as "
           + VALUE_ALIAS
           + " from ("
           + selectQueryBuilder.toString()
           + ") tmp_table";
   selectQueryBuilder.append(" limit ").append(start).append(", ").append(count);
   final String listQuery = selectQueryBuilder.toString();
   try {
     return new ListResponse(
         start,
         runner.query(listCountQuery, new SingleValuedResultHandler()),
         runner.query(listQuery, new SavedQueryResultSetHandler()));
   } catch (SQLException e) {
     throw new LensException("List query failed!", e);
   }
 }
Esempio n. 2
0
 protected Map<String, Serializable> computeConversionParameters(UriInfo uriInfo) {
   MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
   Map<String, Serializable> parameters = new HashMap<>();
   for (String parameterKey : queryParams.keySet()) {
     parameters.put(parameterKey, queryParams.getFirst(parameterKey));
   }
   return parameters;
 }
 @GET
 @Path("views/{model}")
 public Response views(@PathParam("model") String model) {
   final MultivaluedMap<String, String> params = getUriInfo().getQueryParameters(true);
   final Map<String, String> views = Maps.newHashMap();
   for (String mode : params.keySet()) {
     views.put(mode, params.getFirst(mode));
   }
   return service.findViews(findClass(model), views);
 }
Esempio n. 4
0
  protected ResourceState getCurrentState(ResourceState serviceDocument, String resourcePath) {
    ResourceState state = null;
    if (resourcePath != null) {
      /*
       * add a leading '/' if it needs it (when defining resources we must use a
       * full path, but requests can be relative, i.e. without a '/'
       */
      if (!resourcePath.startsWith("/")) {
        resourcePath = "/" + resourcePath;
      }
      // add service document path to resource path
      String serviceDocumentPath = serviceDocument.getPath();
      if (serviceDocumentPath.endsWith("/")) {
        serviceDocumentPath =
            serviceDocumentPath.substring(0, serviceDocumentPath.lastIndexOf("/"));
      }
      resourcePath = serviceDocumentPath + resourcePath;
      // turn the uri back into a template uri
      MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
      if (pathParameters != null) {
        for (String key : pathParameters.keySet()) {
          List<String> values = pathParameters.get(key);
          for (String value : values) {
            resourcePath = resourcePath.replace(value, "{" + key + "}");
          }
        }
      }
      String httpMethod = requestContext.getMethod();
      Event event = new Event(httpMethod, httpMethod);
      state = resourceStateProvider.determineState(event, resourcePath);

      if (state == null) {
        logger.warn("No state found, dropping back to path matching " + resourcePath);
        // escape the braces in the regex
        resourcePath = Pattern.quote(resourcePath);
        Map<String, Set<String>> pathToResourceStates =
            resourceStateProvider.getResourceStatesByPath();
        for (String path : pathToResourceStates.keySet()) {
          for (String name : pathToResourceStates.get(path)) {
            ResourceState s = resourceStateProvider.getResourceState(name);
            String pattern = null;
            if (s instanceof CollectionResourceState) {
              pattern = resourcePath + "(|\\(\\))";
              Matcher matcher = Pattern.compile(pattern).matcher(path);
              if (matcher.matches()) {
                state = s;
              }
            }
          }
        }
      }
    }
    return state;
  }
 public void setQueryParameters(MultivaluedMap<String, String> queryParams) {
   if (_queryParams != null) {
     for (String key : queryParams.keySet()) {
       List<String> values = queryParams.get(key);
       for (String value : values) {
         _queryParams.add(key, value);
       }
     }
   } else {
     _queryParams = queryParams;
   }
 }
 public List<String> getDimensions(
     String collection, MultivaluedMap<String, String> selectedDimensionValues) throws Exception {
   CollectionSchema schema = dataCache.getCollectionSchema(serverUri, collection);
   Set<String> selectedDimensions =
       (selectedDimensionValues == null ? null : selectedDimensionValues.keySet());
   if (CollectionUtils.isEmpty(selectedDimensions)) {
     return schema.getDimensions();
   }
   List<String> filteredDimensions =
       new ArrayList<>(CollectionUtils.subtract(schema.getDimensions(), selectedDimensions));
   Collections.sort(filteredDimensions);
   return filteredDimensions;
 }
    @Override
    public void filter(ContainerRequestContext request) throws IOException {

      logger.debug("Filtering {}", request.getUriInfo().getRequestUri().toString());

      if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
        logger.debug("Skipping option request");
      }

      MultivaluedMap<java.lang.String, java.lang.String> params = uriInfo.getPathParameters();
      logger.debug("Params: {}", params.keySet());

      authorize(request);
    }
Esempio n. 8
0
 private void _test(ClientRequest request, UriBuilder uriBuilder, String path) {
   request.clear();
   uriBuilder.replacePath(generateURL(path));
   try {
     ClientResponse<String> response = request.get(String.class);
     Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
     MultivaluedMap<String, String> headers = response.getHeaders();
     for (Object key : headers.keySet()) {
       System.out.println(key + ": " + headers.get(key));
     }
     response.releaseConnection();
   } catch (Exception e) {
     throw new RuntimeException(e);
   }
 }
Esempio n. 9
0
    @Produces(MediaType.TEXT_PLAIN)
    @GET
    @Path("/matrix/{id}")
    public String matrixparamtest(@PathParam("id") PathSegment id) {
      StringBuffer sb = new StringBuffer();
      sb.append("matrix=");

      sb.append("/" + id.getPath());
      MultivaluedMap<String, String> matrix = id.getMatrixParameters();
      Set<String> keys = matrix.keySet();
      for (Object key : keys) {
        sb.append(";" + key.toString() + "=" + matrix.getFirst(key.toString()));
      }
      return sb.toString();
    }
 @GET
 @Produces("text/plain")
 @Path("decoded/segment/matrix/{params}")
 public String getDecodedSegmentMatrixParam(@PathParam("params") PathSegment segment) {
   MultivaluedMap<String, String> map = segment.getMatrixParameters();
   Iterator<String> it = map.keySet().iterator();
   System.out.println("getDecodedSegmentMatrixParam(): decoded matrix params: ");
   StringBuilder builder = new StringBuilder();
   while (it.hasNext()) {
     String key = it.next();
     System.out.println("  " + key + "->" + map.getFirst(key));
     builder.append(map.getFirst(key));
   }
   return builder.toString();
 }
  @GET
  @Path("chart/{name}")
  public Response chart(@PathParam("name") String name) {
    final MultivaluedMap<String, String> params = getUriInfo().getQueryParameters(true);
    final Map<String, Object> context = Maps.newHashMap();
    final Request request = new Request();

    for (String key : params.keySet()) {
      List<String> values = params.get(key);
      if (values.size() == 1) {
        context.put(key, values.get(0));
      } else {
        context.put(key, values);
      }
    }
    request.setData(context);

    return service.getChart(name, request);
  }
Esempio n. 12
0
  /**
   * Update/Set the profile information (foaf) for the current user. Post-Body should contain the
   * property=value mapping (propterty without foaf-prefix) for the profile.
   *
   * @param formParams the user profile (foaf, without prefix) in {@value
   *     Namespaces#MIME_TYPE_FORM_URLENC}
   * @return {@link AccountPoJo} after the update in JSON @HTTP 403 When the current user is <code>
   *     anonymous</code>. @HTTP 500 If a {@link RepositoryException} occurs (which should not
   *     happen as no namespaces are used here)
   */
  @POST
  @Path("/me")
  @Consumes(Namespaces.MIME_TYPE_FORM_URLENC)
  public Response post(MultivaluedMap<String, String> formParams) {
    final URI currentUser = userService.getCurrentUser();
    if (userService.isAnonymous(currentUser))
      return Response.status(Status.FORBIDDEN).entity("anonymous is read-only").build();

    try {
      RepositoryConnection conn = sesameService.getConnection();

      try {
        for (String prop : formParams.keySet()) {
          if (!acceptedFoafProperties.contains(prop)) {
            continue;
          }
          URI p = conn.getValueFactory().createURI(Namespaces.NS_FOAF + prop);

          conn.remove(currentUser, p, null);

          String val = formParams.getFirst(prop);
          if (val != null && val.length() > 0) {
            Matcher m = PROFILE_URI_PATTERN.matcher(val);
            if (m.matches()) {
              URI o = conn.getValueFactory().createURI(m.group(1));
              conn.add(currentUser, p, o, currentUser);
            } else {
              Literal o = conn.getValueFactory().createLiteral(val.trim());
              conn.add(currentUser, p, o, currentUser);
            }
          }
        }
        return get(currentUser);
      } finally {
        conn.commit();
        conn.close();
      }
    } catch (RepositoryException e) {
      // This must not happen!
      return Response.serverError().entity(e).build();
    }
  }
Esempio n. 13
0
  @SuppressWarnings("unchecked")
  public static HttpServletRequest correctPostRequest(
      final MultivaluedMap<String, String> formParams, HttpServletRequest httpServletRequest) {
    final HashMap<String, Object> formParamsHashMap = new HashMap<String, Object>();

    for (String key : formParams.keySet()) {
      Object value = formParams.get(key);
      if (value instanceof List) {
        Object[] valueArray = ((List) value).toArray();
        formParamsHashMap.put(key, valueArray);
      } else {
        formParamsHashMap.put(key, value);
      }
    }

    HttpServletRequestWrapper requestWrapper =
        new HttpServletRequestWrapper(httpServletRequest) {
          @Override
          public Map getParameterMap() {
            return formParamsHashMap;
          }

          @Override
          public String[] getParameterValues(String name) {
            return (String[]) formParamsHashMap.get(name);
          }

          @Override
          public String getParameter(String name) {
            Object value = formParamsHashMap.get(name);
            if (value != null && value instanceof String[] && ((String[]) value)[0] != null) {
              return ((String[]) value)[0];
            } else {
              return null;
            }
          }
        };

    return requestWrapper;
  }
Esempio n. 14
0
  public static String dumpResponse(Response r, boolean detailed, String fieldDelim) {
    String s = "[Response obiect] ";
    s += "status=" + r.getStatus();
    s += fieldDelim + "statusInfo=" + r.getStatusInfo();
    s += fieldDelim + "location=" + r.getLocation();

    if (!detailed) return s;

    MultivaluedMap<String, String> headersStrings = r.getStringHeaders();
    Iterator<String> it = headersStrings.keySet().iterator();
    s += "\n---- headers ---";
    while (it.hasNext()) {
      String theKey = it.next();
      s += "\n" + theKey + ":";
      List<String> valuesList = headersStrings.get(theKey);
      for (String value : valuesList) {
        s += value + ",";
      }
    }

    return s;
  }
Esempio n. 15
0
  /**
   * Obtain the specified action property. An action property can either contain a simple value or
   * reference a link property. If it is the latter it will obtain the referenced value stored in
   * the link property. e.g. GetEntities filter=myfilter and myfilter="CreditAcctNo eq '{Acc}'",
   * Acc="CreditAcctNo" => filter=CreditAcctNo eq '{CreditAcctNo}'
   *
   * @param propertyName Action property name
   * @param actionProperties Action properties
   * @param queryParameters Query parameters (keys)
   * @return Action property string
   */
  protected static String getActionProperty(
      String propertyName,
      Properties actionProperties,
      MultivaluedMap<String, String> queryParameters) {
    Object propObj = actionProperties.get(propertyName);
    if (propObj != null && propObj instanceof ActionPropertyReference) {
      ActionPropertyReference propRef = (ActionPropertyReference) propObj;
      Set<String> queryParamKeys = queryParameters.keySet();

      if (queryParameters.containsKey(propRef.getKey())) {
        return queryParameters.getFirst(propRef.getKey());
      }

      String key = "_";
      for (String queryParamKey : queryParamKeys) {
        if (!queryParamKey.startsWith("$")) { // Do not consider $filter, $select, etc.
          key += "_" + queryParamKey;
        }
      }
      return propRef.getProperty(key);
    } else {
      return actionProperties.get(propertyName).toString(); // e.g. fld eq '{code}'
    }
  }
Esempio n. 16
0
  private InputStream createInputStream(
      final HttpServletRequest request, final MultivaluedMap<String, String> form)
      throws IOException {
    // /!\ Kludge alert (pierre) /!\
    // This is awful... But because of various servlet filters we have in place, include Shiro,
    // the request parameters and/or body at this point have already been looked at.
    // We can't use @FormParam in PluginResource because we don't know the form parameter names
    // in advance.
    // So... We just stick them back in :-)
    // TODO Support application/x-www-form-urlencoded vs multipart/form-data
    final ByteArrayOutputStream out = new ByteArrayOutputStream();

    final Map<String, String> data = new HashMap<String, String>();
    for (final String key : request.getParameterMap().keySet()) {
      data.put(key, request.getParameter(key));
    }
    for (final String key : form.keySet()) {
      data.put(key, form.getFirst(key));
    }
    appendFormParametersToBody(out, data);

    ByteStreams.copy(request.getInputStream(), out);
    return new ByteArrayInputStream(out.toByteArray());
  }
 @Override
 public Set<K> keySet() {
   return Collections.unmodifiableSet(delegate.keySet());
 }
Esempio n. 18
0
  private String verifyResponse(
      Response resp, String content, int status, HashMap<String, String> expected_map)
      throws Exception {
    boolean pass = true;
    StringBuffer sb = new StringBuffer();

    sb.append("========== Verifying a Response with Map: " + newline);

    String entity = (String) resp.getEntity();

    if ((content == null) || (content == "")) {
      if (!(resp.getEntity() == null) || (resp.getEntity() == "")) {
        pass = false;
        sb.append(
            indent
                + "Entity verification failed: expecting no content, got "
                + (String) resp.getEntity()
                + newline);
      }
    } else if (!content.equals(((String) resp.getEntity()))) {
      pass = false;
      sb.append(
          indent
              + "Entity verification failed: expecting "
              + content
              + ", got "
              + (String) resp.getEntity()
              + newline);
    } else {
      sb.append(
          indent + "Correct content found in Response: " + (String) resp.getEntity() + newline);
    }

    if (resp.getStatus() != status) {
      pass = false;
      sb.append(
          indent
              + "Status code verification failed: expecting "
              + status
              + ", got "
              + resp.getStatus()
              + newline);
    } else {
      sb.append(indent + "Correct status found in Response: " + status + newline);
    }

    MultivaluedMap<java.lang.String, java.lang.Object> mvp = resp.getMetadata();
    if (expected_map == null) {
      sb.append(
          indent
              + "No keys to verify or expected, but found the following keys in Response:"
              + newline);
      for (String key : mvp.keySet()) {
        sb.append(indent + indent + "Key: " + key + "; " + mvp.getFirst(key) + ";" + newline);
      }
    } else {
      for (String key_actual : mvp.keySet()) {
        sb.append(indent + "Response contains key: " + key_actual + newline);
      }
      sb.append(indent + "Verifying the following keys in Response:" + newline);
      String actual, expected = null;
      for (Map.Entry<String, String> entry : expected_map.entrySet()) {
        String key = entry.getKey();
        if (!mvp.containsKey(key)) {
          pass = false;
          sb.append(indent + indent + "Key: " + key + " is not found in Response;" + newline);
        } else if (key.equalsIgnoreCase("last-modified")) {
          sb.append(indent + indent + "Key Last-Modified is found in response" + newline);
        } else {
          expected = entry.getValue().toLowerCase();
          actual = mvp.getFirst(key).toString().toLowerCase();

          if (actual.startsWith("\"") && actual.endsWith("\"")) {
            actual = actual.substring(1, actual.length() - 1);
          }

          if (!actual.equals(expected)) {
            pass = false;
            sb.append(
                indent
                    + indent
                    + "Key: "
                    + key
                    + " found in Response, but with different value;"
                    + newline);
            sb.append(
                indent
                    + indent
                    + "Expecting "
                    + entry.getValue()
                    + "; got "
                    + mvp.getFirst(key)
                    + newline);
          }
          sb.append(
              indent
                  + indent
                  + "Processed key "
                  + key
                  + " with expected value "
                  + entry.getValue()
                  + newline);
        }
      }
    }
    sb.append(indent + pass);
    return sb.toString();
  }
 @Override
 public boolean containsKey(final Object key) {
   return getInsensitiveKeySet(delegate.keySet()).contains(key.toString());
 }
Esempio n. 20
0
  protected void applyQueryFilters(
      final MultivaluedMap<String, String> p, final CriteriaBuilder builder) {
    final MultivaluedMap<String, String> params = new MultivaluedMapImpl();
    params.putAll(p);

    builder.distinct();
    builder.limit(DEFAULT_LIMIT);

    // not sure why we remove this, but that's what the old query filter code did, I presume there's
    // a reason  :)
    params.remove("_dc");

    if (params.containsKey("limit")) {
      builder.limit(Integer.valueOf(params.getFirst("limit")));
      params.remove("limit");
    }
    if (params.containsKey("offset")) {
      builder.offset(Integer.valueOf(params.getFirst("offset")));
      params.remove("offset");
    }
    // Is this necessary anymore? setLimitOffset() comments implies it's for Ext-JS.
    if (params.containsKey("start")) {
      builder.offset(Integer.valueOf(params.getFirst("start")));
      params.remove("start");
    }

    if (params.containsKey("orderBy")) {
      builder.orderBy(params.getFirst("orderBy"));
      params.remove("orderBy");

      if (params.containsKey("order")) {
        if ("desc".equalsIgnoreCase(params.getFirst("order"))) {
          builder.desc();
        } else {
          builder.asc();
        }
        params.remove("order");
      }
    }

    final String query = removeParameter(params, "query");
    if (query != null) builder.sql(query);

    final String matchType;
    final String match = removeParameter(params, "match");
    if (match == null) {
      matchType = "all";
    } else {
      matchType = match;
    }
    builder.match(matchType);

    final Class<?> criteriaClass = builder.toCriteria().getCriteriaClass();
    final BeanWrapper wrapper = getBeanWrapperForClass(criteriaClass);

    final String comparatorParam = removeParameter(params, "comparator", "eq").toLowerCase();
    final Criteria currentCriteria = builder.toCriteria();

    for (final String key : params.keySet()) {
      for (final String paramValue : params.get(key)) { // NOSONAR
        // NOSONAR the interface of MultivaluedMap.class declares List<String> as return value,
        // the actual implementation com.sun.jersey.core.util.MultivaluedMapImpl returns a String,
        // so this is fine in some way ...
        if ("null".equalsIgnoreCase(paramValue)) {
          builder.isNull(key);
        } else if ("notnull".equalsIgnoreCase(paramValue)) {
          builder.isNotNull(key);
        } else {
          Object value;
          Class<?> type = Object.class;
          try {
            type = currentCriteria.getType(key);
          } catch (final IntrospectionException e) {
            LOG.debug("Unable to determine type for key {}", key);
          }
          if (type == null) {
            type = Object.class;
          }
          LOG.warn("comparator = {}, key = {}, propertyType = {}", comparatorParam, key, type);

          if (comparatorParam.equals("contains")
              || comparatorParam.equals("iplike")
              || comparatorParam.equals("ilike")
              || comparatorParam.equals("like")) {
            value = paramValue;
          } else {
            LOG.debug("convertIfNecessary({}, {})", key, paramValue);
            try {
              value = wrapper.convertIfNecessary(paramValue, type);
            } catch (final Throwable t) {
              LOG.debug("failed to introspect (key = {}, value = {})", key, paramValue, t);
              value = paramValue;
            }
          }

          try {
            final Method m =
                builder.getClass().getMethod(comparatorParam, String.class, Object.class);
            m.invoke(builder, new Object[] {key, value});
          } catch (final Throwable t) {
            LOG.warn(
                "Unable to find method for comparator: {}, key: {}, value: {}",
                comparatorParam,
                key,
                value,
                t);
          }
        }
      }
    }
  }
Esempio n. 21
0
  /**
   * Returns a SolrDocumentList for a given set of search parameters. Search parameters are parsed
   * and mapped into solr (solrj) query syntax, and solr query is performed.
   *
   * @param queryParams query parameters to map to a solr query
   * @return the SolrDocumentList for this query
   * @see SolrDocumentList
   */
  private SolrDocumentList doQuery(MultivaluedMap<String, String> queryParams) {
    SolrDocumentList docs = null;
    HttpSolrServer server = null;
    ArrayList<String> queryList = new ArrayList<String>();
    server = SolrServer.getSolrConnection();
    SolrQuery query = new SolrQuery();
    for (String key : queryParams.keySet()) {
      String value = queryParams.getFirst(key);
      System.out.println(key + " : " + queryParams.getFirst(key) + "\n");
      if (key.equals("start")) {
        int startNo = Integer.parseInt(value);
        if (startNo < 0) startNo = 0;
        query.setStart(startNo);
      } else if (key.equals("limit")) {
        limit = Integer.parseInt(value);
        query.setRows(limit);
      } else if (key.equals("sort.asc") || key.equals("sort")) query.setSort(value, ORDER.asc);
      else if (key.equals("sort.desc")) query.setSort(value, ORDER.desc);
      else if (key.startsWith("facet")) {
        query.setFacet(true);
        String[] facetArray = value.split(",");
        for (String f : facetArray) {
          query.addFacetField(f);
        }
      } else {
        if (key.endsWith("_exact")) queryList.add(key.replace("_exact", "") + ":\"" + value + "\"");
        else {
          if (value.contains(" ")) value = "( " + value.replaceAll(" ", " AND ") + ")";
          if (key.equals("q")) queryList.add("keyword:" + value);
          else queryList.add(key + "_keyword:" + value);
        }
      }
    }

    Iterator<String> it = queryList.iterator();
    String queryStr = "";
    while (it.hasNext()) {
      String qTerm = (String) it.next();
      System.out.print("QT: " + qTerm + "\n");
      queryStr += qTerm;
      System.out.print("QS: " + queryStr + "\n");
      if (it.hasNext()) queryStr += " AND ";
    }
    System.out.print("queryStr: " + queryStr);
    query.setQuery(queryStr);
    QueryResponse response = null;
    try {
      response = server.query(query);
    } catch (SolrServerException se) {
      log.error(se.getMessage());
      throw new BadParameterException(se.getMessage());
    } catch (RemoteSolrException rse) {
      if (rse.getMessage().contains("SyntaxError")) {
        log.error("solr syntax error");
        throw new BadParameterException("Incorrect query syntax");
      } else {
        String msg = rse.getMessage().replace("_keyword", "");
        log.error(msg);
        throw new BadParameterException("Incorrect query syntax:" + msg);
      }
    }
    List<FacetField> facets = response.getFacetFields();
    facet = null;
    if (facets != null) {
      facet = new Facet();
      List<FacetType> facetTypes = new ArrayList<FacetType>();
      for (FacetField facetField : facets) {
        List<FacetTerm> facetTerms = new ArrayList<FacetTerm>();
        FacetType facetType = new FacetType();
        facetType.setFacetName(facetField.getName());
        List<FacetField.Count> facetEntries = facetField.getValues();
        for (FacetField.Count fcount : facetEntries) {
          if (fcount.getCount() > 0) {
            FacetTerm facetTerm = new FacetTerm();
            facetTerm.setTermName(fcount.getName());
            facetTerm.setTermCount(fcount.getCount());
            // System.out.println(fcount.getName() + ": " + fcount.getCount());
            facetTerms.add(facetTerm);
          }
        }
        facetType.setFacetTerms(facetTerms);
        facetTypes.add(facetType);
      }
      facet.setFacetTypes(facetTypes);
    }
    docs = response.getResults();
    return docs;
  }
 @Override
 public Set<String> keySet() {
   return getInsensitiveKeySet(delegate.keySet());
 }
 @Override
 public Set<K> keySet() {
   return delegate.keySet();
 }