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 2013/03/24 18:36:54 UTC

svn commit: r1460418 - in /clerezza/trunk/platform.xhtml2html/src/main/java/org/apache/clerezza/platform/xhtml2html: AcceptHeader.java MediaType.java MediaTypeComparator.java Xhtml2HtmlFilter.java

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;
             }
         }