[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