You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@clerezza.apache.org by re...@apache.org on 2010/08/02 00:39:52 UTC
svn commit: r981338 - in
/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs:
./ util/
Author: reto
Date: Sun Aug 1 22:39:52 2010
New Revision: 981338
URL: http://svn.apache.org/viewvc?rev=981338&view=rev
Log:
CLEREZZA-266: comnparing concreteness of matching writer annotation selecting between of accept-headers of same relative preference
Added:
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/InconsistentMediaTypeComparator.java
Modified:
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/ResponseProcessor.java
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/AcceptHeader.java
incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java
Modified: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/ResponseProcessor.java
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/ResponseProcessor.java?rev=981338&r1=981337&r2=981338&view=diff
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/ResponseProcessor.java (original)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/ResponseProcessor.java Sun Aug 1 22:39:52 2010
@@ -34,6 +34,7 @@ import java.security.PrivilegedException
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -61,6 +62,7 @@ import org.apache.clerezza.triaxrs.util.
import org.apache.clerezza.triaxrs.util.FirstByteActionOutputStream;
import org.apache.clerezza.triaxrs.util.MediaTypeComparator;
import org.apache.clerezza.triaxrs.util.BodyStoringResponse;
+import org.apache.clerezza.triaxrs.util.InconsistentMediaTypeComparator;
import org.wymiwyg.wrhapi.HandlerException;
import org.wymiwyg.wrhapi.HeaderName;
import org.wymiwyg.wrhapi.MessageBody;
@@ -139,26 +141,37 @@ class ResponseProcessor {
}
final List<MediaType> expandedMethodProducibleMediaTypesList = expandListWithConcreterTypesFromAccept(methodProducibleMediaTypesList, acceptHeader);
MessageBodyWriter<Object> writer = null;
- Collections.sort(expandedMethodProducibleMediaTypesList,
- new MediaTypeComparator(acceptHeader));
+ List<Set<MediaType>> expandedMethodProducibleMediaTypeClasses
+ = getSortedClasses(expandedMethodProducibleMediaTypesList,
+ new InconsistentMediaTypeComparator(acceptHeader));
Collections.sort(methodProducibleMediaTypesList,
new MediaTypeComparator(acceptHeader));
MediaType relevantMethodProducibleType = null;
- for (MediaType mediaType : expandedMethodProducibleMediaTypesList) {
- writer = (MessageBodyWriter<Object>) JaxRsHandler.providers.getMessageBodyWriter(entity.getClass(), entityType,
- annotations, mediaType);
- if (writer != null) {
- for (MediaType methodMediaType : methodProducibleMediaTypesList) {
- if (methodMediaType.isCompatible(mediaType)) {
- relevantMethodProducibleType = methodMediaType;
- break;
+ for (Set<MediaType> preferenceClass : expandedMethodProducibleMediaTypeClasses) {
+ int lastWriterConcreteness = -1;
+ for (MediaType mediaType : preferenceClass) {
+ MessageBodyWriter<Object> currentWriter = (MessageBodyWriter<Object>) JaxRsHandler.providers.getMessageBodyWriter(entity.getClass(), entityType,
+ annotations, mediaType);
+ if (currentWriter != null) {
+ int writerConcreteness = getWriterConcreteness(currentWriter, mediaType);
+ if (writerConcreteness > lastWriterConcreteness) {
+ for (MediaType methodMediaType : methodProducibleMediaTypesList) {
+ if (methodMediaType.isCompatible(mediaType)) {
+ relevantMethodProducibleType = methodMediaType;
+ break;
+ }
+ }
+ writer = currentWriter;
}
}
+ }
+ if (writer != null) {
break;
}
}
+
if (writer == null) {
for (MediaType mediaType : expandedMethodProducibleMediaTypesList) {
try {
@@ -229,7 +242,7 @@ class ResponseProcessor {
}
}
- if (acceptHeader.getAcceptingMediaType(mediaType) == null) {
+ if (acceptHeader.getAcceptingMediaType(mediaType).isEmpty()) {
if (!mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
throw new WebApplicationException(406);
}
@@ -356,11 +369,10 @@ class ResponseProcessor {
private static List<MediaType> expandListWithConcreterTypesFromAccept(List<MediaType> mediaTypesList, AcceptHeader acceptHeader) {
Collection<MediaType> addition = new HashSet<MediaType>();
for (MediaType mediaType : mediaTypesList) {
- MediaType acceptingType = acceptHeader.getAcceptingMediaType(mediaType);
-
- if ((acceptingType != null) &&
- (MediaTypeComparator.compareByWildCardCount(acceptingType, mediaType) == -1)) {
- addition.add(acceptingType);
+ for (MediaType acceptingType : acceptHeader.getAcceptingMediaType(mediaType)) {
+ if (MediaTypeComparator.compareByWildCardCount(acceptingType, mediaType) == -1) {
+ addition.add(acceptingType);
+ }
}
}
final List<MediaType> result = new ArrayList<MediaType>();
@@ -478,4 +490,67 @@ class ResponseProcessor {
return new MediaType(mediaType.getType(), mediaType.getSubtype(),
resultParams);
}
+
+ /**
+ *
+ * @param <T>
+ * @param collection
+ * @param comparator
+ * @return a list containing sets of instances for which the comparator returns 0
+ * in oder
+ */
+ private static <T> List<Set<T>> getSortedClasses(Collection<T> collection,
+ Comparator<T> comparator) {
+ List<Set<T>> result = new ArrayList<Set<T>>();
+ if (collection.size() > 0) {
+ Set<T> pivotSet = new HashSet<T>();
+ Collection<T> before = new ArrayList<T>();
+ Collection<T> after = new ArrayList<T>();
+ Iterator<T> iterator = collection.iterator();
+ T pivot = iterator.next();
+ pivotSet.add(pivot);
+ while (iterator.hasNext()) {
+ T next = iterator.next();
+ int comparison = comparator.compare(next, pivot);
+ if (comparison > 0) {
+ after.add(next);
+ } else {
+ if (comparison < 0) {
+ before.add(next);
+ } else {
+ pivotSet.add(next);
+ }
+ }
+ }
+ result.addAll(getSortedClasses(before, comparator));
+ result.add(pivotSet);
+ result.addAll(getSortedClasses(after, comparator));
+ }
+ return result;
+
+ }
+
+ /**
+ *
+ * @param writer
+ * @param mediaType
+ * @return 0 is mediaType ismatched only by wildcard in the @Produces of writer,
+ * 1, if the supertype is concrete, 2 if the subtype is concrete too
+ */
+ private static int getWriterConcreteness(MessageBodyWriter<Object> writer, MediaType mediaType) {
+ Produces produces = writer.getClass().getAnnotation(Produces.class);
+ int result = 0;
+ if (produces != null) {
+ for (String producedValue : produces.value()) {
+ MediaType producesType = MediaType.valueOf(producedValue);
+ if (producesType.isCompatible(mediaType)) {
+ int concreteness = 2 - MediaTypeComparator.countWildChars(producesType);
+ if (concreteness > result) {
+ result = concreteness;
+ }
+ }
+ }
+ }
+ return result;
+ }
}
Modified: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/AcceptHeader.java
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/AcceptHeader.java?rev=981338&r1=981337&r2=981338&view=diff
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/AcceptHeader.java (original)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/AcceptHeader.java Sun Aug 1 22:39:52 2010
@@ -19,7 +19,9 @@
package org.apache.clerezza.triaxrs.util;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -123,13 +125,27 @@ public class AcceptHeader {
return 0;
}
- public MediaType getAcceptingMediaType(MediaType type) {
+ /**
+ *
+ * @param type
+ * @return the media-types in the accept header that are would best accept
+ * type, i.e. all pattern with the highest same q-value accepting type are
+ * returned
+ */
+ public Set<MediaType> getAcceptingMediaType(MediaType type) {
+ Set<MediaType> result = new HashSet<MediaType>();
+ double currentQValue = 0;
for (AcceptHeaderEntry acceptHeaderEntry : entries) {
if (acceptHeaderEntry.mediaType.isCompatible(type)) {
- return acceptHeaderEntry.mediaType;
+ if (acceptHeaderEntry.quality >= currentQValue) {
+ currentQValue = acceptHeaderEntry.quality;
+ result.add(acceptHeaderEntry.mediaType);
+ } else {
+ break;
+ }
}
}
- return null;
+ return result;
}
/**
Added: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/InconsistentMediaTypeComparator.java
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/InconsistentMediaTypeComparator.java?rev=981338&view=auto
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/InconsistentMediaTypeComparator.java (added)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/InconsistentMediaTypeComparator.java Sun Aug 1 22:39:52 2010
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.clerezza.triaxrs.util;
+
+import java.util.Comparator;
+
+import javax.ws.rs.core.MediaType;
+
+/**
+ * Sorts media types in accordance with an accept-header inconsistently
+ *
+ * This comparator is not consistent with equals
+ *
+ * @author reto
+ */
+public class InconsistentMediaTypeComparator implements Comparator<MediaType> {
+
+ private AcceptHeader acceptHeader;
+
+ public InconsistentMediaTypeComparator() {
+ }
+
+ public InconsistentMediaTypeComparator(AcceptHeader acceptHeader) {
+ this.acceptHeader = acceptHeader;
+ }
+
+
+
+ @Override
+ public int compare(MediaType o1, MediaType o2) {
+ if (o1.equals(o2)) return 0;
+ if (acceptHeader != null) {
+ if (acceptHeader.getAcceptedQuality(o1) > acceptHeader.getAcceptedQuality(o2)) {
+ return -1;
+ }
+ if (acceptHeader.getAcceptedQuality(o1) < acceptHeader.getAcceptedQuality(o2)) {
+ return 1;
+ }
+ }
+ return MediaTypeComparator.inconsistentCompare(o1, o2);
+
+ }
+
+}
Modified: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java?rev=981338&r1=981337&r2=981338&view=diff
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java (original)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.triaxrs/org.apache.clerezza.triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java Sun Aug 1 22:39:52 2010
@@ -23,8 +23,10 @@ import java.util.Comparator;
import javax.ws.rs.core.MediaType;
/**
- * Uses wirldcard as firts key and q-value as second key (for selecting
- * server-side entities as jax-rs spec ignores q-value in annotations.
+ * Sorts media types in accordance with an accept-header, falling back to literal
+ * sorting to guarantee constistency.
+ *
+ * Also provides static Utility methods for Media Type comparison.
*
* @author reto
*/