// 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].unsafeLock() ;
HTTPFrame itsframe =
(HTTPFrame) resource.unsafeGetFrame(httpFrameClass);
if (itsframe != null) {
if ( itsframe.unsafeDefinesAttribute (ATTR_QUALITY) )
qs = itsframe.unsafeGetQuality() ;
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();