[jboss-cvs] jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui ...

Christian Bauer christian at hibernate.org
Wed Mar 7 13:37:39 EST 2007


  User: cbauer  
  Date: 07/03/07 13:37:39

  Added:       examples/wiki/src/main/org/jboss/seam/wiki/core/ui       
                        FileMetaMap.java Converters.java
                        UIWikiFormattedText.java WikiLink.java
                        WikiUtil.java WikiTextParser.java FileServlet.java
  Log:
  Moved to hot-redeploy WAR build structure
  
  Revision  Changes    Path
  1.1      date: 2007/03/07 18:37:39;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FileMetaMap.java
  
  Index: FileMetaMap.java
  ===================================================================
  package org.jboss.seam.wiki.core.ui;
  
  import org.jboss.seam.annotations.Unwrap;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.AutoCreate;
  
  import java.util.HashMap;
  import java.util.Map;
  
  @Name("fileMetaMap")
  @AutoCreate
  public class FileMetaMap {
  
      public String contentType;
  
      private Map<String, FileMetaInfo> metamap = new HashMap<String, FileMetaInfo>() {
          {
              put("image/jpg",                    new FileMetaInfo("icon.fileimg.gif", true));
              put("image/jpeg",                   new FileMetaInfo("icon.fileimg.gif", true));
              put("image/gif",                    new FileMetaInfo("icon.fileimg.gif", true));
              put("image/png",                    new FileMetaInfo("icon.fileimg.gif", true));
              put("text/plain",                   new FileMetaInfo("icon.filetxt.gif", false));
              put("application/pdf",              new FileMetaInfo("icon.filepdf.gif", false));
              put("application/octet-stream",     new FileMetaInfo("icon.filegeneric.gif", false));
              put("generic",                      new FileMetaInfo("icon.filegeneric.gif", false));
          }
      };
  
      @Unwrap
      public Map<String, FileMetaInfo> getFielMetaMap() {
          return metamap;
      }
  
      public class FileMetaInfo {
          
          public String displayIcon;
          public boolean image;
  
          public FileMetaInfo(String displayIcon, boolean image) {
              this.displayIcon = displayIcon;
              this.image = image;
          }
  
          public String getDisplayIcon() { return displayIcon; }
          public boolean isImage() { return image; }
      }
  }
  
  
  
  1.1      date: 2007/03/07 18:37:39;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/Converters.java
  
  Index: Converters.java
  ===================================================================
  package org.jboss.seam.wiki.core.ui;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.wiki.core.dao.UserDAO;
  import org.jboss.seam.wiki.core.model.Role;
  
  import javax.faces.component.UIComponent;
  import javax.faces.context.FacesContext;
  import javax.faces.convert.Converter;
  import javax.faces.convert.ConverterException;
  import java.io.Serializable;
  
  public class Converters {
  
      @Name("roleConverter")
      @org.jboss.seam.annotations.jsf.Converter(forClass = Role.class)
      public static class RoleConverter implements Converter, Serializable {
  
          public Object getAsObject(FacesContext arg0,
                                    UIComponent arg1,
                                    String arg2) throws ConverterException {
              if (arg2 == null) return null;
              try {
                  return ((UserDAO) Component.getInstance("userDAO")).findRole(Long.valueOf(arg2));
              } catch (NumberFormatException e) {
                  throw new ConverterException("Cannot find selected role", e);
              }
          }
  
          public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) throws ConverterException {
              if (arg2 instanceof Role) {
                  Role role = (Role) arg2;
                  return role.getId().toString();
              } else {
                  return null;
              }
          }
      }
  
  }
  
  
  
  1.1      date: 2007/03/07 18:37:39;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java
  
  Index: UIWikiFormattedText.java
  ===================================================================
  package org.jboss.seam.wiki.core.ui;
  
  import java.io.IOException;
  import java.io.Reader;
  import java.io.StringReader;
  
  import javax.faces.component.UIOutput;
  import javax.faces.context.FacesContext;
  
  import org.jboss.seam.text.SeamTextLexer;
  import org.jboss.seam.wiki.core.ui.WikiTextParser;
  import org.jboss.seam.contexts.Contexts;
  
  import antlr.ANTLRException;
  
  public class UIWikiFormattedText extends UIOutput {
      public static final String COMPONENT_FAMILY = "org.jboss.seam.wiki.core.ui.WikiFormattedText";
  
      @Override
      public String getFamily() {
          return COMPONENT_FAMILY;
      }
  
      @Override
      public void encodeBegin(FacesContext context) throws IOException {
  
          System.out.println("############### GOT IT ");
  
          if (!isRendered() || getValue() == null) return;
          Reader r = new StringReader((String) getValue());
          SeamTextLexer lexer = new SeamTextLexer(r);
  
          // TODO: This getAttribute() stuff is not NPE safe!
  
          // Use the WikiTextParser to resolve links
          WikiTextParser parser =
                  new WikiTextParser(lexer,
                                     getAttributes().get("linkStyleClass").toString(),
                                     getAttributes().get("brokenLinkStyleClass").toString(),
                                     getAttributes().get("attachmentLinkStyleClass").toString(),
                                     getAttributes().get("inlineLinkStyleClass").toString()
                  );
  
          try {
              parser.startRule();
          }
          catch (ANTLRException re) {
              throw new RuntimeException(re);
          }
  
          context.getResponseWriter().write(parser.toString());
  
          // Put attachments (wiki links...) into the event context for later rendering
          Contexts.getEventContext().set("wikiTextAttachments", parser.getAttachments());
      }
  
  
  }
  
  
  
  1.1      date: 2007/03/07 18:37:39;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiLink.java
  
  Index: WikiLink.java
  ===================================================================
  package org.jboss.seam.wiki.core.ui;
  
  import org.jboss.seam.wiki.core.model.Node;
  
  public class WikiLink {
      Node node;
      boolean broken = false;
      String url;
      String description;
      boolean external;
  
      public WikiLink(Node node, boolean broken, String url, String description, boolean external) {
          this.node = node;
          this.url = url;
          this.broken = broken;
          this.description = description;
          this.external = external;
      }
      public Node getNode() { return node; }
      public boolean isBroken() { return broken; }
      public String getUrl() { return url; }
      public String getDescription() { return description; }
      public boolean isExternal() { return external; }
      public String toString() {
          return "Description: " + description + " URL: " + url;
      }
  }
  
  
  
  1.1      date: 2007/03/07 18:37:39;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiUtil.java
  
  Index: WikiUtil.java
  ===================================================================
  package org.jboss.seam.wiki.core.ui;
  
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.wiki.core.model.*;
  import org.jboss.seam.Component;
  
  import javax.faces.component.UIData;
  import javax.faces.context.FacesContext;
  import java.util.Collection;
  
  /**
   * Adds stuff to and for JSF that should be there but isn't. Also stuff that is exposed
   * as a Facelets function, we can't have that in a Seam component - different classloader
   * for hot redeployment of Seam components.
   */
  @Name("wikiUtil")
  public class WikiUtil {
  
      // Replacement for missing instaceOf in EL (can't use string comparison, might be proxy)
      public static boolean isDirectory(Node node) {
          return node != null && Directory.class.isAssignableFrom(node.getClass());
      }
  
      public static boolean isDocument(Node node) {
          return node != null && Document.class.isAssignableFrom(node.getClass());
      }
  
      public static boolean isFile(Node node) {
          return node != null && File.class.isAssignableFrom(node.getClass());
      }
  
      // Allow calling this as a Facelets function in pages
      public static String renderURL(Node node) {
          GlobalPreferences globalPrefs = (GlobalPreferences) Component.getInstance("globalPrefs");
          String contextPath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
  
          if (isFile(node)) {
              return contextPath + "/files/download?fileId=" + node.getId();
          }
  
          if (globalPrefs.getDefaultURLRendering().equals(GlobalPreferences.URLRendering.PERMLINK)) {
              return contextPath + "/" + node.getId() + globalPrefs.getPermlinkSuffix();
          } else {
              if (node.getArea().getWikiname().equals(node.getWikiname()))
                  return contextPath + "/" + node.getArea().getWikiname();
              return contextPath + "/" + node.getArea().getWikiname()  + "/" + node.getWikiname();
          }
      }
  
      /**
       * Need to bind UI components to non-conversational backing beans.
       * That this is even needed makes no sense. Why can't I call the UI components
       * in the EL directly? Don't try components['id'], it won't work.
       */
      private UIData datatable;
      public UIData getDatatable() { return datatable; }
      public void setDatatable(UIData datatable) { this.datatable = datatable; }
  
      /**
       * Can't use col.size() in a value binding. Why can't I call arbitrary methods, even
       * with arguments, in a value binding? Java needs properties badly.
       */
      public static int sizeOf(Collection col) {
          return col.size();
      }
  }
  
  
  
  1.1      date: 2007/03/07 18:37:39;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiTextParser.java
  
  Index: WikiTextParser.java
  ===================================================================
  package org.jboss.seam.wiki.core.ui;
  
  import org.jboss.seam.text.SeamTextParser;
  import org.jboss.seam.core.Expressions;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.wiki.core.model.File;
  import org.jboss.seam.wiki.core.links.WikiLinkResolver;
  import antlr.TokenStream;
  
  import java.util.Map;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.HashMap;
  
  
  public class WikiTextParser extends SeamTextParser {
  
      private String linkClass;
      private String brokenLinkClass;
      private String attachmentLinkClass;
      private String inlineLinkClass;
  
      private List<WikiLink> attachments = new ArrayList<WikiLink>();
      private List<WikiLink> externalLinks = new ArrayList<WikiLink>();
      private Map<String, WikiLink> links = new HashMap<String, WikiLink>();
  
      public WikiTextParser(TokenStream tokenStream,
                            String linkClass, String brokenLinkClass, String attachmentLinkClass, String inlineLinkClass) {
          super(tokenStream);
          this.linkClass = linkClass;
          this.brokenLinkClass = brokenLinkClass;
          this.attachmentLinkClass = attachmentLinkClass;
          this.inlineLinkClass = inlineLinkClass;
      }
  
      protected String linkTag(String descriptionText, String linkText) {
  
          // Resolve the link with loosely coupled calls (resolver is in different classloader during hot deploy)
          Contexts.getEventContext().set("linkMap", links);
          Contexts.getEventContext().set("linkText", linkText.trim());
          Expressions.MethodBinding method = Expressions.instance()
                  .createMethodBinding("#{wikiLinkResolver.resolveWikiLink(linkMap,linkText)}");
          method.invoke();
          //noinspection unchecked
          links = (Map<String, WikiLink>)Contexts.getEventContext().get("linkMap");
  
          WikiLink link = links.get((linkText));
  
          String finalDescriptionText =
                  (descriptionText!=null && descriptionText.length() > 0 ? descriptionText : link.getDescription());
  
          // Link to file (inline or attached)
          if (WikiUtil.isFile(link.getNode())) {
              File file = (File)link.getNode();
  
              if (file.getImageMetaInfo() == null || 'A' == file.getImageMetaInfo().getThumbnail()) {
                  // It's an attachment
                  if (!attachments.contains(link)) attachments.add(link);
                  return "<a href=\"#attachment"
                          + (attachments.indexOf(link)+1)
                          + "\" class=\""
                          + attachmentLinkClass
                          + "\">"
                          + finalDescriptionText
                          + "[" + (attachments.indexOf(link)+1) + "]"
                          + "</a>";
              } else {
                  // It's an image and we need to show it inline
                  int thumbnailWidth;
                  switch(file.getImageMetaInfo().getThumbnail()) {
                      case 'S': thumbnailWidth = 80; break;
                      case 'M': thumbnailWidth = 160; break;
                      case 'L': thumbnailWidth = 320; break;
                      default: thumbnailWidth = file.getImageMetaInfo().getSizeX();
                  }
                  String thumbnailUrl = link.getUrl() + "&width=" + thumbnailWidth;
  
                  return "<a href=\""
                          + link.getUrl()
                          + "\" class=\""
                          + inlineLinkClass
                          + "\"><img src=\""
                          + thumbnailUrl
                          + "\"/></a>";
              }
          }
  
          // External link
          if (link.isExternal() && !externalLinks.contains(link)) externalLinks.add(link);
  
          // Regular link
          return "<a href=\""
                  + link.getUrl()
                  + "\" class=\""
                  + (link.isBroken() ? brokenLinkClass : linkClass)
                  + "\">"
                  + finalDescriptionText
                  + "</a>";
      }
  
      public List<WikiLink> getAttachments() {
          return attachments;
      }
  
      public List<WikiLink> getExternalLinks() {
          return externalLinks;
      }
  }
  
  
  
  1.1      date: 2007/03/07 18:37:39;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java
  
  Index: FileServlet.java
  ===================================================================
  package org.jboss.seam.wiki.core.ui;
  
  import org.jboss.seam.wiki.core.model.File;
  import org.jboss.seam.util.Transactions;
  import org.jboss.seam.core.Expressions;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.annotations.In;
  
  import javax.imageio.ImageIO;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.ServletException;
  import javax.swing.*;
  import javax.transaction.UserTransaction;
  import javax.persistence.EntityManager;
  import java.awt.*;
  import java.awt.image.BufferedImage;
  import java.io.IOException;
  import java.io.ByteArrayOutputStream;
  import java.io.InputStream;
  
  public class FileServlet extends HttpServlet {
  
      private static final String DOWNLOAD_PATH = "/download";
  
      @In
      EntityManager entityManager;
  
      /**
       * The maximum width allowed for image rescaling
       */
      private static final int MAX_IMAGE_WIDTH = 3000;
  
      private byte[] noImage;
  
      public FileServlet() {
          InputStream in = getClass().getResourceAsStream("/img/filenotfound.png");
          if (in != null) {
              ByteArrayOutputStream out = new ByteArrayOutputStream();
              byte[] buffer = new byte[512];
              try {
                  int read = in.read(buffer);
                  while (read != -1) {
                      out.write(buffer, 0, read);
                      read = in.read(buffer);
                  }
  
                  noImage = out.toByteArray();
              }
              catch (IOException e) {
              }
          }
  
      }
  
      @Override
      protected void doGet(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
  
          if (DOWNLOAD_PATH.equals(request.getPathInfo())) {
  
              String id = request.getParameter("fileId");
              File file;
  
              // TODO: Seam should use its transaction interceptor for java beans: http://jira.jboss.com/jira/browse/JBSEAM-957
              UserTransaction userTx = null;
              boolean startedTx = false;
              try {
                  userTx = Transactions.getUserTransaction();
                  if (userTx.getStatus() != javax.transaction.Status.STATUS_ACTIVE) {
                      startedTx = true;
                      userTx.begin();
                  }
  
                  file = (!"".equals(id)) ?
                          ((EntityManager)org.jboss.seam.Component.getInstance("entityManager"))
                                  .find(File.class, Long.parseLong(id))
                          : null;
  
                  if (startedTx) userTx.commit();
              } catch (Exception ex) {
                  try {
                      if (startedTx) userTx.rollback();
                  } catch (Exception rbEx) {
                      rbEx.printStackTrace();
                  }
                  throw new RuntimeException(ex);
              }
  
              String contentType = null;
              byte[] data = null;
  
  
              if (file != null && file.getData() != null && file.getData().length > 0) {
                  contentType = file.getContentType();
                  data = file.getData();
              } else if (noImage != null) {
                  contentType = "image/png";
                  data = noImage;
              }
  
              if (data != null) {
                  response.setContentType(contentType);
  
                  boolean rescale = false;
                  int width = 0;
                  ImageIcon icon = null;
  
                  // Check if the image needs to be rescaled (and if the file is an image)
                  if (request.getParameter("width") != null && file.getImageMetaInfo() != null) {
                      width = Math.min(MAX_IMAGE_WIDTH, Integer.parseInt(request.getParameter("width")));
                      icon = new ImageIcon(data);
                      if (width > 0 && width != icon.getIconWidth())
                          rescale = true;
                  }
  
                  // Rescale the image if required
                  if (rescale) {
                      double ratio = (double) width / icon.getIconWidth();
                      int height = (int) (icon.getIconHeight() * ratio);
  
                      int imageType = "image/png".equals(contentType) ?
                              BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
                      BufferedImage bImg = new BufferedImage(width, height, imageType);
                      Graphics2D g2d = bImg.createGraphics();
                      g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                      g2d.drawImage(icon.getImage(), 0, 0, width, height, null);
                      g2d.dispose();
  
                      String formatName = "";
                      if ("image/png".equals(contentType))
                          formatName = "png";
                      else if ("image/jpeg".equals(contentType))
                          formatName = "jpeg";
  
                      ImageIO.write(bImg, formatName, response.getOutputStream());
                  } else {
                      response.getOutputStream().write(data);
                  }
              }
  
              response.getOutputStream().flush();
          }
      }
  }
  
  
  



More information about the jboss-cvs-commits mailing list