@RequestMapping(value = "/listLinks", method = RequestMethod.POST)
 public ResponseEntity<List<ShortURL>> listLinks(
     @RequestParam(value = "username") String username, HttpServletRequest request) {
   logger.info("Requested list of links from user with username " + username);
   List<ShortURL> list = null;
   if (username != null && !username.equals("")) {
     list = shortURLRepositoryExtended.findByUsername(username);
   }
   if (list != null) {
     return new ResponseEntity<>(list, HttpStatus.ACCEPTED);
   } else {
     return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
   }
 }
 @RequestMapping(value = "/hash", method = RequestMethod.GET)
 public ResponseEntity<ShortURL> hash(
     @RequestParam(value = "hash") String hash, HttpServletRequest request) {
   logger.info("Requested shortURL from hash " + hash);
   ShortURL shortURL = null;
   if (hash != null && !hash.equals("")) {
     shortURL = shortURLRepositoryExtended.findByKey(hash);
   }
   if (shortURL != null) {
     return new ResponseEntity<>(shortURL, HttpStatus.CREATED);
   } else {
     return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
   }
 }
  @RequestMapping(value = "/{name:(?!link|home|login|users|advert).*}", method = RequestMethod.GET)
  public ResponseEntity<?> redirectTo(@PathVariable String name, HttpServletRequest request) {
    logger.info("Requested redirection with hash " + name);
    ShortURL l = shortURLRepositoryExtended.findByKey(name);
    if (l != null) {
      createAndSaveClick(extractIP(request), name);

      String conditionalTarget = exprMatching(name, request, l.getTarget());
      if (conditionalTarget != null) l.setTarget(conditionalTarget);

      return createSuccessfulRedirectToResponse(l);
    } else {
      return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
  }
 @RequestMapping(value = "/deleteLinksUser", method = RequestMethod.POST)
 public ResponseEntity<Boolean> deleteLinksUser(
     @RequestParam(value = "username") String username, HttpServletRequest request) {
   logger.info("Requested deletion of links from user with username " + username);
   boolean borrado = false;
   if (username != null && !username.equals("")) {
     shortURLRepositoryExtended.deleteByUsername(username);
     borrado = true;
   }
   if (borrado) {
     return new ResponseEntity<>(borrado, HttpStatus.ACCEPTED);
   } else {
     return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
   }
 }
 @RequestMapping(value = "/deleteRow", method = RequestMethod.POST)
 public ResponseEntity<Boolean> deleteRow(
     @RequestParam(value = "username") String username,
     @RequestParam(value = "hash") String hash,
     @RequestParam(value = "target") String target,
     HttpServletRequest request) {
   logger.info("Requested deletion of row with hash " + hash + " and target " + target);
   boolean accepted = false;
   if (username != null
       && !username.equals("")
       && hash != null
       && !hash.equals("")
       && target != null
       && !target.equals("")) {
     shortURLRepositoryExtended.deleteByHash(username, hash, target);
     accepted = true;
   }
   if (accepted) {
     return new ResponseEntity<>(accepted, HttpStatus.ACCEPTED);
   } else {
     return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
   }
 }
  protected ShortURL createAndSaveIfValid(
      String url,
      String sponsor,
      String brand,
      String owner,
      String ip,
      String name,
      String username,
      boolean advert,
      int seconds,
      boolean useConditional) {
    UrlValidator urlValidator = new UrlValidator(new String[] {"http", "https"});
    if (urlValidator.isValid(url) || (url.equals("") && useConditional)) {
      ShortURL su = null;
      ResponseEntity<String> entity =
          new RestTemplate().getForEntity("http://ipinfo.io/" + ip + "/json", String.class);
      String json = entity.getBody().toString();
      String country = "";
      try {
        JSONObject obj = new JSONObject(json);
        country = obj.getString("country");
      } catch (JSONException e) {
      }

      if (!name.equals("")) {
        su =
            new ShortURL(
                name,
                url,
                linkTo(methodOn(UrlShortenerControllerWithLogs.class).redirectTo(name, null))
                    .toUri(),
                sponsor,
                new Date(System.currentTimeMillis()),
                owner,
                HttpStatus.TEMPORARY_REDIRECT.value(),
                true,
                ip,
                country,
                username,
                advert,
                seconds);
      } else {
        String id = Hashing.murmur3_32().hashString(url, StandardCharsets.UTF_8).toString();
        su =
            new ShortURL(
                id,
                url,
                linkTo(methodOn(UrlShortenerController.class).redirectTo(id, null)).toUri(),
                sponsor,
                new Date(System.currentTimeMillis()),
                owner,
                HttpStatus.TEMPORARY_REDIRECT.value(),
                true,
                ip,
                country,
                username,
                advert,
                seconds);
      }
      return shortURLRepositoryExtended.save(su);
    } else {
      return null;
    }
  }
  @RequestMapping(value = "/link", method = RequestMethod.POST)
  public ResponseEntity<?> shortener(
      @RequestParam("url") String url,
      @RequestParam(value = "sponsor", required = false) String sponsor,
      @RequestParam(value = "brand", required = false) String brand,
      @RequestParam(value = "urlName", required = false) String name,
      @RequestParam("username") String username,
      @RequestParam(value = "advert", required = false) String advertisement,
      @RequestParam(value = "max", required = false) String max,
      @RequestParam MultiValueMap<String, String> params,
      HttpServletRequest request,
      Principal currentUser,
      Model model) {
    logger.info("Requested new short for uri " + url);
    sponsor = "http://localhost:8080/advert";

    boolean useConditional = false;
    // Comprobamos si se usan URIs condicionales
    if (params.getFirst("ifurl1") != null
        && !params.getFirst("ifurl1").equals("")
        && params.getFirst("expr1") != null
        && !params.getFirst("expr1").equals("")) {
      useConditional = true;
    }

    logger.info("Name (hash) is " + name);
    // Si se usan URIs condicionales pero no hay url estandar,
    // se crea un hash usando las targets de las condicionales
    if (name.equals("") && url.equals("") && useConditional) {
      logger.info("There are Conditional URIs but no default target" + name);
      String ifurl = "ifurl";
      String expr = "expr";
      String nueva = "a";

      int paramn = 1;

      String firstparam = ifurl + paramn;
      String secondparam = expr + paramn;

      while ((params.getFirst(firstparam) != null && params.getFirst(secondparam) != null)
          && (!params.getFirst(firstparam).equals("")
              && !params.getFirst(secondparam).equals(""))) {
        nueva += params.getFirst(firstparam);

        paramn++;
        firstparam = ifurl + paramn;
        secondparam = expr + paramn;
      }

      name =
          Hashing.murmur3_32()
              .hashString(url + username + nueva, StandardCharsets.UTF_8)
              .toString();
      while (shortURLRepositoryExtended.findByHash(name, username) != null) {
        // seguir creando
        name =
            Hashing.murmur3_32()
                .hashString(url + username + "" + nueva, StandardCharsets.UTF_8)
                .toString();
        nueva += "a";
      }
    }

    // Si no existe una hash (id or name) se crea una
    else if (name.equals("")) {
      name = Hashing.murmur3_32().hashString(url + username, StandardCharsets.UTF_8).toString();
      String nueva = "a";
      while (shortURLRepositoryExtended.findByHash(name, username) != null) {
        // seguir creando
        name =
            Hashing.murmur3_32()
                .hashString(url + username + "" + nueva, StandardCharsets.UTF_8)
                .toString();
        nueva += "a";
      }
    }
    logger.info("After name (hash) is " + name);

    boolean advert = false;
    int seconds = 0;
    if (advertisement != null) {
      advert = true;
      if (!max.equals("")) {
        seconds = Integer.valueOf(max);
        if (seconds < 1) {
          seconds = 5;
        }
      }
    }

    if (shortURLRepositoryExtended.findByHash(name, username) != null
        && url != null
        && !url.equals("")) {
      ArrayList<String> sufijos = new ArrayList<String>(); // contiene todos los sufijos
      sufijos.add("ada");
      sufijos.add("aco");
      sufijos.add("ado");
      JSONArray arr = new JSONArray();
      JSONObject tmp;
      try {
        for (int i = 0; i < sufijos.size(); i++) {
          ShortURL l = shortURLRepositoryExtended.findByHash(name + "" + sufijos.get(i), username);
          if (l == null) {
            // No existe en la BD, luego no esta cogido
            tmp = new JSONObject();
            tmp.put("name", name + "" + sufijos.get(i));
            arr.put(tmp);
          }
        }
      } catch (Exception e) {
      }
      String devueltos = "'{\"names\":" + arr.toString() + "}'";

      RiWordnet wordnet = new RiWordnet();

      // Crea 10 sinonimos
      String[] poss = wordnet.getPos(name);
      /*
       * for (int j = 0; j < poss.length; j++) {
       * System.out.println("\n\nSynonyms for " + name + " (pos: " +
       * poss[j] + ")");
       */
      JSONArray sinonimos = new JSONArray();
      try {
        String[] synonyms = wordnet.getAllSynonyms(name, poss[0], 10);
        Arrays.sort(synonyms);
        JSONObject tmpo;
        for (int i = 0; i < synonyms.length; i++) {
          ShortURL l = shortURLRepositoryExtended.findByHash(synonyms[i], username);
          if (l == null) {
            // No existe en la BD, luego no esta cogido
            tmpo = new JSONObject();
            tmpo.put("synonym", synonyms[i]);
            sinonimos.put(tmpo);
          }
        }
      } catch (Exception e) {
      }
      String synDevueltos = "'{\"synonyms\":" + sinonimos.toString() + "}'";
      String respuesta = devueltos + "separa" + synDevueltos;
      return new ResponseEntity<>(respuesta, HttpStatus.NOT_ACCEPTABLE);
    } else {
      ShortURL su =
          createAndSaveIfValid(
              url,
              sponsor,
              brand,
              UUID.randomUUID().toString(),
              extractIP(request),
              name,
              username,
              advert,
              seconds,
              useConditional);
      if (su != null) {
        HttpHeaders h = new HttpHeaders();
        h.setLocation(su.getUri());

        saveConditionalURIs(name, params);

        return new ResponseEntity<>(su, h, HttpStatus.CREATED);
      } else {
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
      }
    }
  }