📄 jpegxmpframe.java
字号:
// JpegXMPFrame.java// $Id: JpegXMPFrame.java,v 1.2 2003/01/27 16:14:55 ylafon Exp $// (c) COPYRIGHT MIT, ERCIM and Keio, 2003.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.jigsaw.frames;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.net.URLEncoder;import org.w3c.www.mime.MimeType;import org.w3c.www.mime.MimeTypeFormatException;import org.w3c.tools.resources.Attribute;import org.w3c.tools.resources.AttributeRegistry;import org.w3c.tools.resources.ProtocolException;import org.w3c.tools.resources.ResourceException;import org.w3c.tools.resources.event.AttributeChangedEvent;import org.w3c.www.http.HTTP;import org.w3c.www.http.HttpAccept;import org.w3c.www.http.HttpEntityTag;import org.w3c.www.http.HttpFactory;import org.w3c.www.http.HttpInvalidValueException;import org.w3c.jigsaw.http.Client;import org.w3c.jigsaw.http.ClientException;import org.w3c.jigsaw.http.HTTPException;import org.w3c.jigsaw.http.Reply;import org.w3c.jigsaw.http.Request;import org.w3c.tools.jpeg.JpegHeaders;import org.w3c.jigsaw.resources.ImageFileResource;/** * This class will read the XMP marker from a jpeg file and return it * depending on the Accept: header */public class JpegXMPFrame extends HTTPFrame { public static final boolean debug = false; /** * Attribute index - The comment content type */ static { Attribute a = null ; Class cls = null ; try { cls = Class.forName("org.w3c.jigsaw.frames.JpegXMPFrame") ; } catch (Exception ex) { ex.printStackTrace() ; System.exit(1) ; } } /** * the static String of the Vary ehader to be added */ protected static String[] vary = { "Accept" }; /** * the static String of the Vary ehader to be added */ protected static MimeType xmptype = MimeType.APPLICATION_RDF_XML ; /** * The comment entity tag */ protected HttpEntityTag xmpetag = null; /** * The XMP. */ protected String xmpinfo = null; /** * Extract the XMP from the jpeg image. * @return the xmp info */ protected String getMetadata() { if (fresource == null) return null; File file = fresource.getFile(); if (file.exists()) { String comments[] = null; try { JpegHeaders headers = new JpegHeaders(file); xmpinfo = headers.getXMP(); } catch (Exception ex) { ex.printStackTrace(); return "unable to get XMP: "+ex.getMessage(); } } return xmpinfo; } /** * Get the comment Etag * @return an instance of HttpEntityTag, or <strong>null</strong> if not * defined. */ public HttpEntityTag getXMPETag() { if (xmpetag == null) { String etag_s = null; if (fresource != null) { long lstamp = fresource.getFileStamp()+1; if ( lstamp >= 0L ) { String soid = Integer.toString(getOid(), 32); String stamp = Long.toString(lstamp, 32); etag_s = Integer.toString(getOid(), 32)+":" + Long.toString(lstamp, 32); } } xmpetag = HttpFactory.makeETag(false, etag_s); } return xmpetag; } /** * Update the cached headers value. * Each resource maintains a set of cached values for headers, this * allows for a nice sped-up in headers marshalling, which - as the * complexity of the protocol increases - becomes a bottleneck. */ protected void updateCachedHeaders() { super.updateCachedHeaders(); if (xmpinfo == null) { xmpinfo = getMetadata(); } } public Reply createXMPReply(Request request, int status) { Reply reply = request.makeReply(status); updateCachedHeaders(); reply.setContent(xmpinfo); reply.setContentType(xmptype); reply.setVary(vary); if ( lastmodified != null ) reply.setHeaderValue(Reply.H_LAST_MODIFIED, lastmodified); if ( contentencoding != null ) reply.setHeaderValue(Reply.H_CONTENT_ENCODING,contentencoding); if ( contentlanguage != null ) reply.setHeaderValue(Reply.H_CONTENT_LANGUAGE,contentlanguage); long maxage = getMaxAge(); if ( maxage >= 0 ) { if (reply.getMajorVersion() >= 1 ) { if (reply.getMinorVersion() >= 1) { reply.setMaxAge((int) (maxage / 1000)); } // If max-age is zero, say what you mean: long expires = (System.currentTimeMillis() + ((maxage == 0) ? -1000 : maxage)); reply.setExpires(expires); } } // Set the date of the reply (round it to secs): reply.setDate((System.currentTimeMillis() / 1000L) * 1000L); reply.setETag(getXMPETag()); reply.setContentLocation(getURL(request).toExternalForm() + ";" + URLEncoder.encode(xmptype.toString())); return reply; } public Reply createXMPReply(Request request) { return createXMPReply(request, HTTP.OK); } /** * Check the <code>If-Match</code> condition of that request. * @param request The request to check. * @return An integer, either <code>COND_FAILED</cond> if condition * was checked, but failed, <code>COND_OK</code> if condition was checked * and succeeded, or <strong>0</strong> if the condition was not checked * at all (eg because the resource or the request didn't support it). */ public int checkIfMatch(Request request, HttpEntityTag etag) { if (fresource != null) { HttpEntityTag tags[] = request.getIfMatch(); if ( tags != null ) { // Good, real validators in use: if ( etag != null ) { // Note: if etag is null this means that the resource has // changed and has not been even emited since then... for (int i = 0 ; i < tags.length ; i++) { HttpEntityTag t = tags[i]; if (t.getTag().equals(etag.getTag())) { if (t.isWeak() || etag.isWeak()) { return COND_WEAK; } else { return COND_OK; } } } } return COND_FAILED; } } return 0; } /** * Check the <code>If-None-Match</code> condition of that request. * @param request The request to check. * @return An integer, either <code>COND_FAILED</cond> if condition * was checked, but failed, <code>COND_OK</code> if condition was checked * and succeeded, or <strong>0</strong> if the condition was not checked * at all (eg because the resource or the request didn't support it). */ public int checkIfNoneMatch(Request request, HttpEntityTag etag) { if (fresource != null) { // Check for an If-None-Match conditional: HttpEntityTag tags[] = request.getIfNoneMatch(); if ( tags != null ) { if ( etag == null ) { return COND_OK; } int status = COND_OK; for (int i = 0 ; i < tags.length ; i++) { HttpEntityTag t = tags[i]; if (t.getTag().equals(etag.getTag())) { if (t.isWeak() || etag.isWeak()) { status = COND_WEAK; } else { return COND_FAILED; } } if (t.getTag().equals("*")) { if (fresource != null) { File f = fresource.getFile(); if (f.exists()) { return COND_FAILED; } } else { return COND_FAILED; } } } return status; } } return 0; } /** * check the validators namely LMT/Etags according to rfc2616 rules * @return An integer, either <code>COND_FAILED</cond> if condition * was checked, but failed, <code>COND_OK</code> if condition was checked * and succeeded, or <strong>0</strong> if the condition was not checked * at all (eg because the resource or the request didn't support it). */ public int checkValidators(Request request, HttpEntityTag etag) { int v_inm = checkIfNoneMatch(request, etag); int v_ims = checkIfModifiedSince(request); if ((v_inm == COND_OK) || (v_ims == COND_OK)) { return COND_OK; } if ((v_inm == COND_FAILED) || (v_ims == COND_FAILED)) { return COND_FAILED; } if ((v_inm == COND_WEAK) || (v_ims == COND_WEAK)) { return COND_OK; } return 0; } /** * Negotiate. * @param request the incomming request. * @return true if the client wants the comment, false if the client * wants the image. */ protected boolean negotiate(Request request) throws ProtocolException { if ( ! request.hasAccept() ) { //return the image return false; } else { // The browser has given some preferences: HttpAccept accepts[] = request.getAccept() ; //two content types image/jpeg and comment-type HttpAccept imgAccept = getMatchingAccept(accepts, getContentType()); HttpAccept xmpAccept = getMatchingAccept(accepts, xmptype); if ((imgAccept != null) && (xmpAccept != null)) { // go for best MIME match first int matchImg = getContentType().match(imgAccept.getMimeType()); int matchXMP = xmptype.match(xmpAccept.getMimeType()); if (matchImg == matchXMP) { // equals, use quality return (imgAccept.getQuality() < xmpAccept.getQuality()); } else { return (matchImg < matchXMP); } } else if (xmpAccept != null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -