Author: reto
Date: Sun Mar 24 17:36:54 2013
New Revision: 1460418

URL: http://svn.apache.org/r1460418
Log:
CLEREZZA-759: correctly parsing accept-header

Added:
    
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/AcceptHeader.java
    
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaType.java
    
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaTypeComparator.java
      - copied, changed from r1460378, 
clerezza/branches/wrhapi/triaxrs/triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java
Modified:
    
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/Xhtml2HtmlFilter.java

Added: 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/AcceptHeader.java
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/AcceptHeader.java?rev=1460418&view=auto
==============================================================================
--- 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/AcceptHeader.java
 (added)
+++ 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/AcceptHeader.java
 Sun Mar 24 17:36:54 2013
@@ -0,0 +1,180 @@
+/*
+ * 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.platform.xhtml2html;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author reto
+ */
+public class AcceptHeader {
+
+
+
+       @Override
+       public String toString() {
+               return entries.toString();
+       }
+       private static final Logger logger = 
LoggerFactory.getLogger(AcceptHeader.class);
+
+       static class AcceptHeaderEntry implements 
Comparable<AcceptHeader.AcceptHeaderEntry> {
+
+               private MediaTypeComparator mediaTypeComparator = new 
MediaTypeComparator();
+               MediaType mediaType;
+               int quality; //from 0 to 1000
+
+               AcceptHeaderEntry(MediaType mediaType) {
+                       Map<String, String> parametersWithoutQ = new 
HashMap<String, String>();
+                       parametersWithoutQ.putAll(mediaType.getParameters());
+                       String qValue = parametersWithoutQ.remove("q");
+                       this.mediaType = new MediaType(mediaType.getType(),
+                                       mediaType.getSubtype(), 
parametersWithoutQ);
+                       if (qValue == null) {
+                               quality = 1000;
+                       } else {
+                               quality = (int) (Float.parseFloat(qValue) * 
1000);
+                       }
+               }
+
+               @Override
+               public int compareTo(AcceptHeader.AcceptHeaderEntry o) {
+                       if (equals(o)) {
+                               return 0;
+                       }
+                       if (quality == o.quality) {
+                               return mediaTypeComparator.compare(mediaType, 
o.mediaType);
+                       }
+                       return (o.quality - quality);
+               }
+
+               @Override
+               public String toString() {
+                       // TODO Auto-generated method stub
+                       return mediaType + " with q=" + quality + ";";
+               }
+       }
+       private SortedSet<AcceptHeader.AcceptHeaderEntry> entries = new 
TreeSet<AcceptHeader.AcceptHeaderEntry>();
+
+       public AcceptHeader(Enumeration<String> entryStrings) {
+               if ((entryStrings == null) || 
(!entryStrings.hasMoreElements())) {
+                       entries.add(new 
AcceptHeader.AcceptHeaderEntry(MediaType.WILDCARD_TYPE));
+               } else {
+            while (entryStrings.hasMoreElements()) {
+                String string =entryStrings.nextElement();
+                               try {
+                                       entries.add(new 
AcceptHeader.AcceptHeaderEntry(MediaType.valueOf(string)));
+                               } catch (IllegalArgumentException ex) {
+                                       logger.warn("The string \"" + string + 
"\" is not a valid mediatype", ex);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * 
+        * @return a sorted list of the Mediatypes
+        */
+       public List<MediaType> getEntries() {
+               List<MediaType> result = new ArrayList<MediaType>();
+               for (AcceptHeader.AcceptHeaderEntry entry : entries) {
+                       result.add(entry.mediaType);
+               }
+               return result;
+       }
+
+       /**
+        * 
+        * @param type
+        * @return a value from 0 to 1000 to indicate the quality in which type 
is accepted
+        */
+       public int getAcceptedQuality(MediaType type) {
+               for (AcceptHeader.AcceptHeaderEntry acceptHeaderEntry : 
entries) {
+                       if (isSameOrSubtype(type, acceptHeaderEntry.mediaType)) 
{
+                               return acceptHeaderEntry.quality;
+                       }
+               }
+               
+               Object[] reverseEntries = entries.toArray();
+               for(int i = entries.size()-1; i >=0 ; i--){
+                       AcceptHeader.AcceptHeaderEntry entry = 
(AcceptHeader.AcceptHeaderEntry)reverseEntries[i];
+                       if (isSameOrSubtype(entry.mediaType, type)){
+                               return entry.quality;
+                       }
+               }
+               
+               return 0;
+       }
+
+       /**
+        *
+        * @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 (AcceptHeader.AcceptHeaderEntry acceptHeaderEntry : 
entries) {
+                       if (acceptHeaderEntry.mediaType.isCompatible(type)) {
+                               if (acceptHeaderEntry.quality >= currentQValue) 
{
+                                       currentQValue = 
acceptHeaderEntry.quality;
+                                       result.add(acceptHeaderEntry.mediaType);
+                               } else {
+                                       break;
+                               }
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * 
+        * @param t1
+        * @param t2
+        * @return true if t1 is the same or a subtype or t2 such as when t1 is
+        *         text/plain and t2 is text/*
+        */
+       private boolean isSameOrSubtype(MediaType t1, MediaType t2) {
+               String type1 = t1.getType();
+               String subtype1 = t1.getSubtype();
+               String type2 = t2.getType();
+               String subtype2 = t2.getSubtype();
+
+               if (type2.equals(MediaType.MEDIA_TYPE_WILDCARD) && 
subtype2.equals(MediaType.MEDIA_TYPE_WILDCARD)) {
+                       return true;
+               } else if (type1.equalsIgnoreCase(type2) && 
subtype2.equals(MediaType.MEDIA_TYPE_WILDCARD)) {
+                       return true;
+               } else {
+                       return type1.equalsIgnoreCase(type2) && 
subtype1.equalsIgnoreCase(subtype2);
+               }
+       }
+}

Added: 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaType.java
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaType.java?rev=1460418&view=auto
==============================================================================
--- 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaType.java
 (added)
+++ 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaType.java
 Sun Mar 24 17:36:54 2013
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.platform.xhtml2html;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public class MediaType {
+    static MediaType APPLICATION_XHTML_XML_TYPE = new MediaType("application", 
"xhtml+xml", null);
+    static final MediaType WILDCARD_TYPE = new MediaType("*", "*", null);
+    static final String MEDIA_TYPE_WILDCARD = "*";
+    static MediaType TEXT_HTML_TYPE = new MediaType("text", "html", null);
+
+    static MediaType valueOf(String string) {
+        String[] parts = string.split(";");
+        MediaType result = valueOfParamLess(parts[0]);
+        for (int i = 1; i < parts.length; i++) {
+            parseParam(parts[i], result);
+        }
+        return result;
+    }
+    
+    static MediaType valueOfParamLess(String string) {
+        String[] parts = string.split("/");
+        Map<String, String> parameters = new HashMap<String, String>();
+        MediaType result = new MediaType(parts[0], parts[1], parameters);
+        return result;
+    }
+
+    private static void parseParam(String string, MediaType result) {
+        String[] parts = string.split("=");
+        result.parameters.put(parts[0], parts[1]);
+    }
+    
+    private final String type;
+    private final String subtype;
+    private Map<String, String> parameters;
+
+    MediaType(String type, String subtype, Map<String, String> parameters) {
+        this.type = type;
+        this.subtype = subtype;
+        this.parameters = parameters;
+    }
+
+    Map<String,String> getParameters() {
+        return parameters;
+    }
+
+    String getType() {
+        return type;
+    }
+
+    String getSubtype() {
+        return subtype;
+    }
+
+    /**
+     * for now parameters are ignored
+     */
+       public boolean isCompatible(MediaType other) {
+               if (other == null) {
+                       return false;
+               }
+               if (isWildcardType() || other.isWildcardType()) {
+                       return true;
+               }
+        if (!type.equals(other.getType())) {
+            return false;
+        }
+        if (isWildcardSubtype() || other.isWildcardSubtype()) {
+            return true;
+        }
+        return subtype.equals(other.subtype);
+       }
+
+    private boolean isWildcardSubtype() {
+        return subtype.equals("*");
+    }
+    private boolean isWildcardType() {
+        return type.equals("*");
+    }
+    
+}

Copied: 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaTypeComparator.java
 (from r1460378, 
clerezza/branches/wrhapi/triaxrs/triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java)
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaTypeComparator.java?p2=clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaTypeComparator.java&p1=clerezza/branches/wrhapi/triaxrs/triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java&r1=1460378&r2=1460418&rev=1460418&view=diff
==============================================================================
--- 
clerezza/branches/wrhapi/triaxrs/triaxrs/src/main/java/org/apache/clerezza/triaxrs/util/MediaTypeComparator.java
 (original)
+++ 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/MediaTypeComparator.java
 Sun Mar 24 17:36:54 2013
@@ -16,13 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.clerezza.triaxrs.util;
+package org.apache.clerezza.platform.xhtml2html;
 
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.ws.rs.core.MediaType;
+
 
 /**
  * Sorts media types in accordance with an accept-header, falling back to

Modified: 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/Xhtml2HtmlFilter.java
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/Xhtml2HtmlFilter.java?rev=1460418&r1=1460417&r2=1460418&view=diff
==============================================================================
--- 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/Xhtml2HtmlFilter.java
 (original)
+++ 
clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html/Xhtml2HtmlFilter.java
 Sun Mar 24 17:36:54 2013
@@ -21,8 +21,6 @@ package org.apache.clerezza.platform.xht
 import java.io.IOException;
 import java.util.Enumeration;
 import java.util.regex.Pattern;
-import javax.activation.MimeType;
-import javax.activation.MimeTypeParseException;
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -55,17 +53,7 @@ import org.osgi.service.component.Compon
 public class Xhtml2HtmlFilter implements Filter {
 
     private Pattern[] patterns;
-    final MimeType xhtmlMimeType;
-    final MimeType htmlMimeType;
 
-    {
-        try {
-            xhtmlMimeType = new MimeType("application", "xhtml+xml");
-            htmlMimeType = new MimeType("text", "html");
-        } catch (MimeTypeParseException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
 
     private boolean isApplicable(final HttpServletRequest request) {
         if (htmlPreferredInAccept(request)) {
@@ -85,13 +73,12 @@ public class Xhtml2HtmlFilter implements
 
     private boolean htmlPreferredInAccept(HttpServletRequest request) {
         Enumeration<String> accepts = request.getHeaders("Accept");
-        //TODO parse geader
-        while (accepts.hasMoreElements()) {
-            final String accept = accepts.nextElement();
-            if (accept.startsWith("application/xhtml+xml")) {
+        AcceptHeader acceptHeader = new AcceptHeader(accepts);
+        for (MediaType accept : acceptHeader.getEntries()) {
+            if (accept.isCompatible(MediaType.APPLICATION_XHTML_XML_TYPE)) {
                 return false;
             }
-            if (accept.startsWith("text/html")) {
+            if (accept.isCompatible(MediaType.TEXT_HTML_TYPE)) {
                 return true;
             }
         }


Reply via email to