001/* 002 * This file is part of the JDrupes non-blocking HTTP Codec 003 * Copyright (C) 2017 Michael N. Lipp 004 * 005 * This program is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU Lesser General Public License as published 007 * by the Free Software Foundation; either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 013 * License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License along 016 * with this program; if not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jdrupes.httpcodec.types; 020 021import java.text.ParseException; 022import java.util.Collections; 023import java.util.Map; 024 025public abstract class MediaBase 026 extends ParameterizedValue<MediaBase.MediaTypePair> { 027 028 /** 029 * Create a new object with the given type and no parameters. 030 * 031 * @param type the type 032 */ 033 protected MediaBase(MediaTypePair type) { 034 super(type, Collections.emptyMap()); 035 } 036 037 /** 038 * Create a new object with the given type and parameters. 039 * 040 * @param type the type 041 * @param parameters the parameters 042 */ 043 protected MediaBase(MediaTypePair type, Map<String, String> parameters) { 044 super(type, parameters); 045 } 046 047 /** 048 * Returns the top-level type. 049 * 050 * @return the type 051 */ 052 public String topLevelType() { 053 return value().topLevelType; 054 } 055 056 /** 057 * Returns the subtype 058 * 059 * @return the subtype 060 */ 061 public String subtype() { 062 return value().subtype; 063 } 064 065 /** 066 * Represents the tuple media top-level type and subtype, 067 * including a media range (type or subtype 068 * equals "`*`"). 069 */ 070 public static class MediaTypePair { 071 072 public static final MediaTypePair ALL_MEDIA 073 = new MediaTypePair("*", "*"); 074 075 private String topLevelType; 076 private String subtype; 077 078 /** 079 * Create a new object with the given type and subtype. 080 * 081 * @param type the type 082 * @param subtype the subtype 083 */ 084 public MediaTypePair(String type, String subtype) { 085 super(); 086 this.topLevelType = type.toLowerCase(); 087 this.subtype = subtype.toLowerCase(); 088 } 089 090 /** 091 * Create a main type from its textual representation. 092 * 093 * @param text the textual representation 094 * @return the result 095 * @throws ParseException if the text is ill-formed 096 */ 097 public static MediaTypePair fromString(String text) 098 throws ParseException { 099 int sepPos = text.indexOf('/'); 100 if (sepPos <= 0 || sepPos > text.length() - 2) { 101 throw new ParseException( 102 "Format not \"type/subtype\": " + text, 0); 103 } 104 return new MediaTypePair(text.substring(0, sepPos), 105 text.substring(sepPos + 1)); 106 107 } 108 109 /** 110 * Returns the top-level type. 111 * 112 * @return the type 113 */ 114 public String topLevelType() { 115 return topLevelType; 116 } 117 118 /** 119 * Returns the subtype 120 * 121 * @return the subtype 122 */ 123 public String subtype() { 124 return subtype; 125 } 126 127 /* (non-Javadoc) 128 * @see java.lang.Object#toString() 129 */ 130 @Override 131 public String toString() { 132 return topLevelType + "/" + subtype; 133 } 134 135 /* (non-Javadoc) 136 * @see java.lang.Object#hashCode() 137 */ 138 @Override 139 public int hashCode() { 140 final int prime = 31; 141 int result = 1; 142 result = prime * result 143 + ((subtype == null) ? 0 : subtype.hashCode()); 144 result = prime * result + ((topLevelType == null) ? 0 : topLevelType.hashCode()); 145 return result; 146 } 147 148 /* (non-Javadoc) 149 * @see java.lang.Object#equals(java.lang.Object) 150 */ 151 @Override 152 public boolean equals(Object obj) { 153 if (this == obj) { 154 return true; 155 } 156 if (obj == null) { 157 return false; 158 } 159 if (getClass() != obj.getClass()) { 160 return false; 161 } 162 MediaBase.MediaTypePair other = (MediaBase.MediaTypePair) obj; 163 if (subtype == null) { 164 if (other.subtype != null) { 165 return false; 166 } 167 } else if (!subtype.equals(other.subtype)) { 168 return false; 169 } 170 if (topLevelType == null) { 171 if (other.topLevelType != null) { 172 return false; 173 } 174 } else if (!topLevelType.equals(other.topLevelType)) { 175 return false; 176 } 177 return true; 178 } 179 } 180 181 public static class MediaTypePairConverter 182 implements Converter<MediaTypePair> { 183 184 @Override 185 public String asFieldValue(MediaTypePair value) { 186 return value.toString(); 187 } 188 189 @Override 190 public MediaTypePair fromFieldValue(String text) 191 throws ParseException { 192 return MediaTypePair.fromString(text); 193 } 194 } 195 196}