Code with Finding: |
class NegotiatedFrame { /** * Negotiate among the various variants for the Resource. * We made our best efforts to be as compliant as possible to the HTTP/1.0 * content negotiation algorithm. * @param request the incomming request. * @return a RefourceReference instance. * @exception ProtocolException If one of the variants doesn't exist. */ protected ResourceReference negotiate (Request request) throws ProtocolException { // Check for zero or one variant: ResourceReference variants[] = getVariantResources() ; if (variants == null) { try { getResource().delete(); } catch (MultipleLockException ex) { //will be deleted later... } finally { Reply reply = request.makeReply(HTTP.NOT_FOUND); reply.setContent ("<h1>Document not found</h1>"+ "<p>The document "+request.getURL()+ " has no acceptable variants "+ "(probably deleted)."); throw new HTTPException (reply); } } if ( variants.length < 2 ) { if ( variants.length == 0 ) { try { getResource().delete(); } catch (MultipleLockException ex) { //will be deleted later... } finally { Reply reply = request.makeReply(HTTP.NOT_FOUND); reply.setContent ("<h1>Document not found</h1>"+ "<p>The document "+request.getURL()+ " has no acceptable variants "+ "(probably deleted)."); throw new HTTPException (reply); } } else { return variants[0] ; } } // Build a vector of variant negociation states, one per variants: Vector states = new Vector (variants.length) ; for (int i = 0 ; i < variants.length ; i++) { double qs = 1.0 ; try { FramedResource resource = (FramedResource)variants[i].lock() ; HTTPFrame itsframe = (HTTPFrame) resource.getFrame(httpFrameClass); if (itsframe != null) { if ( itsframe.definesAttribute ("quality") ) qs = itsframe.getQuality() ; if ( qs > REQUIRED_QUALITY ) states.addElement(new VariantState (variants[i], qs)) ; } } catch (InvalidResourceException ex) { //FIXME } finally { variants[i].unlock(); } } // Content-encoding negociation: if ( debug ) printNegotiationState ("init:", states) ; if ( negotiateContentEncoding (states, request) ) // Remains a single acceptable variant: return ((VariantState) states.elementAt(0)).getResource() ; if ( debug ) printNegotiationState ("encoding:", states) ; // Charset quality negociation: if ( negotiateCharsetQuality (states, request) ) // Remains a single acceptable variant: return ((VariantState) states.elementAt(0)).getResource() ; if ( debug ) printNegotiationState ("charset:", states) ; // Language quality negociation: if ( negotiateLanguageQuality (states, request) ) // Remains a single acceptable variant: return ((VariantState) states.elementAt(0)).getResource() ; if ( debug ) printNegotiationState ("language:", states) ; // Content-type negociation: if ( negotiateContentType (states, request) ) // Remains a single acceptable variant: return ((VariantState) states.elementAt(0)).getResource() ; if ( debug ) printNegotiationState ("type:", states) ; // If we reached this point, this means that multiple variants are // acceptable at this point. Keep the ones that have the best quality. if ( debug ) printNegotiationState ("before Q selection:", states) ; double qmax = REQUIRED_QUALITY ; for (int i=0; i< states.size() ; ) { VariantState state = (VariantState) states.elementAt(i) ; if ( state.getQ() > qmax ) { for (int j = i ; j > 0 ; j--) states.removeElementAt(0) ; qmax = state.getQ() ; i = 1 ; } else { if ( state.getQ() < qmax) states.removeElementAt(i) ; else i++; } } if ( debug ) printNegotiationState ("After Q selection:", states) ; if ( qmax == REQUIRED_QUALITY ) { Reply reply = request.makeReply(HTTP.NOT_ACCEPTABLE) ; HtmlGenerator g = new HtmlGenerator("No acceptable"); g.append("<P>The resource cannot be served according to the " + "headers sent</P>"); reply.setStream (g) ; throw new HTTPException (reply) ; } else if ( states.size() == 1 ) { return ((VariantState) states.elementAt(0)).getResource() ; } else { // Respond with multiple choice (for the time being, there should // be a parameter to decide what to do. Reply reply = request.makeReply(HTTP.MULTIPLE_CHOICE) ; HtmlGenerator g = new HtmlGenerator ("Multiple choice for "+ resource.getIdentifier()) ; g.append ("<ul>") ; for (int i = 0 ; i < states.size() ; i++) { VariantState state = (VariantState) states.elementAt(i) ; String name = null; ResourceReference rr = state.getResource(); try { name = rr.lock().getIdentifier(); g.append ("<li>" + "<a href=\"" + name + "\">" + name + "</a>" + " Q= " + state.getQ()) ; } catch (InvalidResourceException ex) { //FIXME } finally { rr.unlock(); } } reply.setStream (g) ; reply.setHeaderValue(reply.H_VARY, getVary()); throw new HTTPException (reply) ; } }
}
|