Example #1
0
  public Resolution save() throws DaoException {
    Link newLink = null;

    // Attach link to logged in user.
    link.user = getLoggedInUser();

    try {
      newLink =
          (Link)
              getDaoManager()
                  .transaction(
                      new DaoCommand() {
                        @Override
                        public Object execute() throws DaoException {
                          Link newLink =
                              getDaoManager()
                                  .getLinkDao()
                                  .create(link.build(getDaoManager().getLinkThumbsUtil()));

                          if (newLink != null && thumb != null) {
                            // Create thumbnails. Unfortunately a connection will
                            // remain open when this happens, but we do need to roll
                            // back if something bad happens.
                            // TODO: this could be done inside the LinkDao; however,
                            // we would need to pass the BufferedImage to it (in the
                            // Link.Builder?).
                            linkThumbsUtil.create(newLink, thumb);
                          }

                          return newLink;
                        }
                      });
    } catch (Exception e) {
      if (newLink != null && thumb != null) {
        // Something went wrong, clean up after ourselves.
        linkThumbsUtil.delete(newLink);
      }

      ValidationErrors errors = new ValidationErrors();

      errors.addGlobalError(new ScopedLocalizableError("validation", "daoException"));

      // NOTE: There are a couple of options how to do this, one:
      // return new ForwardResolution(this.getClass(), "details");
      // or two:
      getContext().setValidationErrors(errors);
      return getContext().getSourcePageResolution();
    }

    return new RedirectResolution(ViewLinkActionBean.class)
        .addParameter("link", newLink.getId())
        .addParameter("title", newLink.getUrlSafeTitle());
  }
Example #2
0
  @ValidationMethod(on = "save", priority = 4) // Most expensive .: done last and if no errors.
  public void validateThumbUrl(ValidationErrors errors) {
    if (link.sourceThumbUrl == null) {
      // This is optional, so validation should occur only if there is a
      // value; however, we must set __some__ value for when this Link is
      // created.
      link.sourceThumbUrl = "";
      return;
    }

    ByteArrayOutputStream outputStream = null;
    HttpURLConnection conn = null;
    InputStream inputStream = null;

    try {
      URL url = new URL(link.sourceThumbUrl);

      // TODO: can this follow cyclic redirects forever?
      HttpURLConnection.setFollowRedirects(true);
      conn = (HttpURLConnection) url.openConnection();
      conn.setReadTimeout(1500);
      conn.setConnectTimeout(1500);
      conn.setRequestMethod("GET");

      if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
        errors.add(THUMB_URL_FIELD, new ScopedLocalizableError("validation", "urlNotFound"));
        return;
      }

      if (!conn.getContentType().startsWith("image/")) {
        errors.add(THUMB_URL_FIELD, new ScopedLocalizableError("validation", "imageInvalidType"));
        return;
      }

      if (conn.getContentLength() > THUMB_MAX_BYTES) {
        errors.add(THUMB_URL_FIELD, new ScopedLocalizableError("validation", "imageTooLarge"));
        return;
      }

      inputStream = conn.getInputStream();
      outputStream = new ByteArrayOutputStream();

      int totalBytesRead = 0;
      byte[] buffer = new byte[URL_READ_BUFFER_SIZE];
      while (totalBytesRead < THUMB_MAX_BYTES) {
        int bytesToRead = Math.min(buffer.length, THUMB_MAX_BYTES - totalBytesRead);
        int bytesRead = inputStream.read(buffer, 0, bytesToRead);

        if (bytesRead > 0) {
          outputStream.write(buffer, 0, bytesRead);
          totalBytesRead += bytesRead;
        } else if (bytesRead == -1) {
          break;
        }
      }

      if (inputStream.read() != -1) {
        errors.add(THUMB_URL_FIELD, new ScopedLocalizableError("validation", "imageTooLarge"));
        return;
      }
    } catch (MalformedURLException e) {
      logger.debug("Malformed URL: " + e);
      errors.add(THUMB_URL_FIELD, new ScopedLocalizableError("validation", "urlMalformed"));
      return;
    } catch (IOException e) {
      logger.debug("URL not found: " + e);
      errors.add(THUMB_URL_FIELD, new ScopedLocalizableError("validation", "urlNotFound"));
      return;
    } finally {
      // Make sure we clean up any InputStream-s and/or connections.
      if (inputStream != null) {
        try {
          inputStream.close();
        } catch (IOException ex) {
        }
      }
      if (conn != null) {
        conn.disconnect();
      }
    }

    try {
      thumb = ImageIO.read(new ByteArrayInputStream(outputStream.toByteArray()));
    } catch (IOException e) {
      logger.debug("Thumbnail cannot be interpretted as image: " + e);
      errors.add(THUMB_URL_FIELD, new ScopedLocalizableError("validation", "imageInvalid"));
      return;
    }
  }