📄 negotiatedframe.java
字号:
// NegotiatedFrame.java// $Id: NegotiatedFrame.java,v 1.41 2004/01/13 16:16:54 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.jigsaw.frames;import java.io.PrintStream;import java.util.Vector;import org.w3c.tools.resources.Attribute;import org.w3c.tools.resources.AttributeHolder;import org.w3c.tools.resources.AttributeRegistry;import org.w3c.tools.resources.BooleanAttribute;import org.w3c.tools.resources.DirectoryResource;import org.w3c.tools.resources.FramedResource;import org.w3c.tools.resources.InvalidResourceException;import org.w3c.tools.resources.LookupState;import org.w3c.tools.resources.LookupResult;import org.w3c.tools.resources.MultipleLockException;import org.w3c.tools.resources.ProtocolException;import org.w3c.tools.resources.ReplyInterface;import org.w3c.tools.resources.RequestInterface;import org.w3c.tools.resources.Resource;import org.w3c.tools.resources.ResourceException;import org.w3c.tools.resources.ResourceFrame;import org.w3c.tools.resources.ResourceReference;import org.w3c.tools.resources.ServerInterface;import org.w3c.tools.resources.StringArrayAttribute;import org.w3c.jigsaw.http.HTTPException;import org.w3c.jigsaw.http.Reply;import org.w3c.jigsaw.http.Request;import org.w3c.jigsaw.html.HtmlGenerator;import org.w3c.jigsaw.html.HtmlGenerator ;import org.w3c.www.mime.LanguageTag;import org.w3c.www.mime.MimeType;import org.w3c.www.http.HTTP;import org.w3c.www.http.HttpAccept;import org.w3c.www.http.HttpAcceptCharset;import org.w3c.www.http.HttpAcceptEncoding;import org.w3c.www.http.HttpAcceptLanguage;import org.w3c.www.http.HttpEntityMessage;import org.w3c.www.http.HttpEntityTag;import org.w3c.www.http.HttpFactory;import org.w3c.www.http.HttpInvalidValueException;import org.w3c.www.http.HttpMessage;import org.w3c.www.http.HttpReplyMessage;import org.w3c.www.http.HttpRequestMessage;import org.w3c.www.http.HttpTokenList;import org.w3c.tools.resources.ProtocolException;import org.w3c.tools.resources.ResourceException;/** * Content negotiation. */public class NegotiatedFrame extends HTTPFrame { class VariantState { ResourceReference variant = null ; double qs = 0.0 ; // configured frame quality double qe = 0.0 ; // content encoding quality double qc = 0.0 ; // content charset quality double ql = 0.0 ; // content language quality double q = 0.0 ; // quality (mime type one) double Q = 0.0 ; // the big Q public String toString() { try { Resource res = variant.unsafeLock(); String name = (String) res.getIdentifier() ; if ( name == null ) name = "<noname>" ; return "[" + name + " qc=" + qc + " qs=" + qs + " qe=" + qe + " ql=" + ql + " q =" + q + " Q =" + getQ() +"]" ; } catch (InvalidResourceException ex) { return "invalid"; } finally { variant.unlock(); } } void setCharsetQuality (double qc) { this.qc = qc ; } double getCharsetQuality () { return qc; } void setContentEncodingQuality (double qe) { this.qe = qe ; } void setContentEncodingQuality (HttpAcceptEncoding e) { this.qe = e.getQuality(); } double getContentEncodingQuality () { return qe ; } void setQuality (double q) { this.q = q ; } void setQuality (HttpAccept a) { q = a.getQuality() ; } void setLanguageQuality (double ql) { this.ql = ql ; } void setLanguageQuality (HttpAcceptLanguage l) { this.ql = l.getQuality() ; } double getLanguageQuality () { return ql ; } ResourceReference getResource () { return variant ; } double getQ() { return qe * q * qs * ql * qc; } VariantState (ResourceReference variant, double qs) { this.qs = qs ; this.variant = variant ; } } private static Class httpFrameClass = null; private static Class negotiatedFrameClass = null; static { try { httpFrameClass = Class.forName("org.w3c.jigsaw.frames.HTTPFrame") ; } catch (Exception ex) { throw new RuntimeException("No HTTPFrame class found."); } try { negotiatedFrameClass = Class.forName("org.w3c.jigsaw.frames.NegotiatedFrame") ; } catch (Exception ex) { throw new RuntimeException("No NegotiatedFrame class found."); } } /** * Our Icon property. */ public static String NEGOTIATED_ICON_P = "org.w3c.jigsaw.frames.negotiated.icon"; /** * Our default Icon */ public static String DEFAULT_NEGOTIATED_ICON = "generic.gif"; /** * our state */ protected static String STATE_NEG = "org.w3c.jigsaw.frames.Negotiated"; /** * Turn debugging on/off. */ private static final boolean debug = false; /** * Minimum quality for a resource to be considered further. */ private static final double REQUIRED_QUALITY = 0.0001 ; /** * The Vary header field for this resource */ protected HttpTokenList vary = null; private boolean vary_done = false; /** * Attribute index - The set of names of variants. */ protected static int ATTR_VARIANTS = -1 ; /** * Attribute index - Should the PUT needs to be strictly checked? */ protected static int ATTR_PUT_POLICY = -1; /** * Attribute index - Should the variants to be strictly checked? * the variants should NEVER contain negotiated resources! */ protected static int ATTR_PARANOID_VARIANT_CHECK = -1; static { Attribute a = null ; Class cls = null ; try { cls = Class.forName("org.w3c.jigsaw.frames.NegotiatedFrame") ; } catch (Exception ex) { ex.printStackTrace() ; System.exit(1) ; } // The names of the varint we negotiate a = new StringArrayAttribute("variants" , null , Attribute.EDITABLE) ; ATTR_VARIANTS = AttributeRegistry.registerAttribute(cls, a) ; a = new BooleanAttribute("strict_put" , new Boolean(true) , Attribute.EDITABLE); ATTR_PUT_POLICY = AttributeRegistry.registerAttribute(cls, a) ; a = new BooleanAttribute("paranoid_variant_check" , new Boolean(false) , Attribute.EDITABLE); ATTR_PARANOID_VARIANT_CHECK = AttributeRegistry.registerAttribute(cls, a) ; } public synchronized void setValue(int idx, Object value) { if ( idx == ATTR_VARIANTS ){ super.setValue(idx,checkVariants((String[])value)); } else { super.setValue(idx,value); } } private HttpTokenList getVary() { if (vary_done) { return vary; } // ok let's do it! vary_done = true; boolean b_charset = false; boolean b_type = false; boolean b_language = false; boolean b_encoding = false; ResourceReference variants[] = null; try { variants = getVariantResources() ; } catch (ProtocolException ex) {}; // no vary for so few variants! if ((variants == null) || (variants.length < 2)) { return null; } synchronized (this) { int num = 0; HTTPFrame refframe = null; FramedResource resource = null; do { try { resource = (FramedResource)variants[num].unsafeLock(); refframe = (HTTPFrame) resource.getFrame(httpFrameClass); } catch (InvalidResourceException ex) { //ex.printStackTrace(); //FIXME } catch (Exception fex) { fex.printStackTrace(); } finally { variants[num].unlock(); } num++; } while ((refframe == null) && (num < variants.length)); // not enough variants, abort if (variants.length - num < 1) return null; String language = refframe.getContentLanguage(); String encoding = refframe.getContentEncoding(); String charset = refframe.getCharset(); MimeType mtype = refframe.getContentType(); HTTPFrame itsframe = null; for (int i = num; i < variants.length; i++) { try { resource = (FramedResource)variants[i].unsafeLock(); itsframe = (HTTPFrame) resource.getFrame(httpFrameClass); if (language != null) { if (!language.equals(itsframe.getContentLanguage())) { b_language = true; } } else { if (itsframe.getContentLanguage() != null) { b_language = true; } } if (encoding != null) { if (!encoding.equals(itsframe.getContentEncoding())) { b_encoding = true; } } else { if (itsframe.getContentEncoding() != null) { b_encoding = true; } } if (charset != null) { if (!charset.equals(itsframe.getCharset())) { b_charset = true; } } else { if (itsframe.getCharset() != null) { b_charset = true; } } if (mtype != null) { MimeType o_type = itsframe.getContentType(); if ((o_type != null) && (mtype.match(o_type) != MimeType.MATCH_SPECIFIC_SUBTYPE)) { b_type = true; } } else { if (itsframe.getContentType() != null) { b_type = true; } } } catch (InvalidResourceException ex) { //ex.printStackTrace(); //FIXME } finally { variants[i].unlock(); } } int vary_size = 0; if (b_language) { vary_size++; } if (b_charset) { vary_size++; } if (b_encoding) { ++vary_size; } if (b_type) { ++vary_size; } if (vary_size == 0) { return null; } String[] s_vary = new String[vary_size]; num = 0; if (b_type) { s_vary[num++] = "Accept"; } if (b_encoding) { s_vary[num++] = "Accept-Encoding"; } if (b_language) { s_vary[num++] = "Accept-Language"; } if (b_charset) { s_vary[num] = "Accept-Charset"; } vary = HttpFactory.makeStringList(s_vary); } return vary; } public String getIcon() { String icon = super.getIcon(); if (icon == null) { icon = getServer().getProperties().getString(NEGOTIATED_ICON_P, DEFAULT_NEGOTIATED_ICON); setValue(ATTR_ICON, icon); } return icon; } /** * Get the variant names. */ public String[] getVariantNames() { return (String[]) getValue(ATTR_VARIANTS, null) ; } protected String[] checkVariants(String variants[]) { Vector checked = new Vector(variants.length) ; ResourceReference tmpres = null; ResourceReference r_parent = resource.getParent() ; try { DirectoryResource parent= (DirectoryResource)r_parent.unsafeLock(); for (int i = 0 ; i < variants.length ; i++) { tmpres = parent.lookup(variants[i]) ; if (tmpres != null) { try { FramedResource resource = (FramedResource)tmpres.unsafeLock() ; NegotiatedFrame itsframe = (NegotiatedFrame) resource.getFrame(negotiatedFrameClass); if (itsframe == null) { checked.addElement (variants[i]); } } catch (InvalidResourceException ex) { } finally { tmpres.unlock(); } } else { checked.addElement (variants[i]); } } } catch (InvalidResourceException ex) { // throw new HTTPException("invalid parent for negotiation"); } finally { r_parent.unlock(); } String[] variants_ok = new String[checked.size()]; checked.copyInto(variants_ok); return variants_ok ; } public void setVariants(String variants[]) { setValue(ATTR_VARIANTS, variants); // invalidate the Vary header vary_done = false; } /** * get the "strictness" of the PUT checking
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -