@Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {

    request.setCharacterEncoding(Charsets.UTF_8.name());
    response.setCharacterEncoding(Charsets.UTF_8.name());
    chain.doFilter(request, response);
  }
Exemple #2
0
 public static CharsetDecoder createUtf8Decoder() {
   if (LENIENT_CODING) {
     return Charsets.UTF_8
         .newDecoder()
         .onMalformedInput(CodingErrorAction.REPLACE)
         .onUnmappableCharacter(CodingErrorAction.REPLACE);
   } else {
     return Charsets.UTF_8
         .newDecoder()
         .onMalformedInput(CodingErrorAction.REPORT)
         .onUnmappableCharacter(CodingErrorAction.REPORT);
   }
 }
 private HttpRequest signForTemporaryAccess(HttpRequest request, long timeInSeconds) {
   // Update the 'DATE' header
   String dateString = request.getFirstHeaderOrNull(HttpHeaders.DATE);
   if (dateString == null) {
     dateString = timeStampProvider.get();
   }
   Date date = dateService.rfc1123DateParse(dateString);
   String expiration =
       String.valueOf(TimeUnit.MILLISECONDS.toSeconds(date.getTime()) + timeInSeconds);
   HttpRequest.Builder<?> builder =
       request.toBuilder().replaceHeader(HttpHeaders.DATE, expiration);
   String stringToSign = authSigner.createStringToSign(builder.build());
   // We MUST encode the signature because addQueryParam internally _always_ decodes values
   // and if we don't encode the signature here, the decoding may change the signature. For e.g.
   // any '+' characters in the signature will be converted to space ' ' on decoding.
   String signature = authSigner.sign(stringToSign);
   try {
     signature = URLEncoder.encode(signature, Charsets.UTF_8.name());
   } catch (UnsupportedEncodingException e) {
     throw new IllegalStateException("Bad encoding on input: " + signature, e);
   }
   HttpRequest ret =
       builder
           .addQueryParam(HttpHeaders.EXPIRES, expiration)
           .addQueryParam("AWSAccessKeyId", identity)
           // Signature MUST be the last parameter because if it isn't, even encoded '+' values in
           // the
           // signature will be converted to a space by a subsequent addQueryParameter.
           // See HttpRequestTest.testAddBase64AndUrlEncodedQueryParams for more details.
           .addQueryParam(TEMPORARY_SIGNATURE_PARAM, signature)
           .build();
   return ret;
 }
 @Override
 public void define(Context context) {
   NewRepository repository =
       context.createRepository(REPOSITORY_KEY, Python.KEY).setName(REPOSITORY_NAME);
   xmlLoader.load(repository, getClass().getResourceAsStream(RULES_FILE), Charsets.UTF_8.name());
   SqaleXmlLoader.load(repository, SQALE_FILE);
   repository.done();
 }
 public static String urlEncode(final String str) {
   try {
     return URLEncoder.encode(str, Charsets.UTF_8.name());
   } catch (final UnsupportedEncodingException e) {
     // shouldn't happen
     throw new RuntimeException(e);
   }
 }
Exemple #6
0
  static String appendSignature(OpenPgp openPgp, String xmlText, String keySpecifier)
      throws IOException {
    xmlText += "\n";

    byte[] xmlData = Charsets.UTF_8.encode(xmlText).array();
    String signature = base64().encode(openPgp.sign(xmlData, keySpecifier));
    return xmlText + "<!-- Base64 Signature\n" + signature + "\n-->\n";
  }
 private void saveLog(final IGeoLog log, final File logFile) {
   try {
     final IStatusCollection statusCollection = log.getStatusCollection();
     final GMLWorkspace workspace = statusCollection.getWorkspace();
     GmlSerializer.serializeWorkspace(logFile, workspace, Charsets.UTF_8.name());
   } catch (IOException | GmlSerializeException e) {
     e.printStackTrace();
   }
 }
Exemple #8
0
 @Test
 public void testPrintNullDelimitedTargets() throws UnsupportedEncodingException {
   Iterable<String> targets = ImmutableList.of("//foo:bar", "//foo:baz");
   FakeOutputStream fakeStream = new FakeOutputStream();
   PrintStream printStream = new PrintStream(fakeStream);
   TargetsCommand.printNullDelimitedTargets(targets, printStream);
   printStream.flush();
   assertEquals("//foo:bar\0//foo:baz\0", fakeStream.toString(Charsets.UTF_8.name()));
 }
  @Test
  public void should_ignore_PMD_error() throws PMDException, FileNotFoundException {
    when(inputFile.getFile()).thenReturn(new File("source.java"));
    when(inputFile.getInputStream()).thenReturn(inputStream);
    doThrow(new PMDException("BUG"))
        .when(pmd)
        .processFile(inputStream, Charsets.UTF_8.displayName(), rulesets, ruleContext);

    new PmdTemplate(pmd).process(inputFile, Charsets.UTF_8, rulesets, ruleContext);
  }
  @Test
  public void should_process_input_file() throws PMDException, FileNotFoundException {
    when(inputFile.getFile()).thenReturn(new File("source.java"));
    when(inputFile.getInputStream()).thenReturn(inputStream);

    new PmdTemplate(pmd).process(inputFile, Charsets.UTF_8, rulesets, ruleContext);

    verify(ruleContext).setSourceCodeFilename(new File("source.java").getAbsolutePath());
    verify(pmd).processFile(inputStream, Charsets.UTF_8.displayName(), rulesets, ruleContext);
  }
Exemple #11
0
 protected void configureDslUiProjectFactory(PluginProjectFactory factory) {
   configureProjectFactory(factory);
   factory.addFolders(singletonList(XTEND_GEN_ROOT));
   List<String> requiredBundles = getDslUiProjectRequiredBundles();
   factory.setProjectName(getXtextProjectInfo().getUiProjectName());
   factory.addProjectNatures(getDslUiProjectNatures());
   factory.addRequiredBundles(requiredBundles);
   factory.setProjectDefaultCharset(Charsets.UTF_8.name());
   factory.setLocation(getXtextProjectInfo().getUiProjectLocation());
 }
 public ContainerRequest request(String uri, String method, ByteBuffer content) {
   ByteArrayOutputStream bos = new ByteArrayOutputStream();
   try {
     ByteStreams.copy(new ByteArrayInputStream(content.array()), bos);
     return request(
         uri, method, bos.toString(Charsets.UTF_8.name()), MediaType.APPLICATION_JSON_TYPE);
   } catch (Exception e) {
     throw new MinnalJaxrsTestException(e);
   }
 }
 /**
  * Write to the given {@link java.io.OutputStream}.
  *
  * @param stream a {@link java.io.OutputStream} instance
  * @return {@code this}
  */
 public T outputTo(OutputStream stream) {
   try {
     this.output = new PrintStream(stream, false, Charsets.UTF_8.toString());
   } catch (UnsupportedEncodingException exception) {
     LOGGER.error(
         "Unsupported encoding in OutputStreamReporter. This is an error with the code itself.",
         exception);
     throw new RuntimeException(exception);
   }
   return self();
 }
    @ProcessInput
    @Batch(100)
    public void foo(Iterator<StreamEvent> it) {
      List<StreamEvent> events = ImmutableList.copyOf(it);
      LOG.warn("Number of batched stream events = " + events.size());
      Assert.assertTrue(events.size() > 1);

      List<Integer> out = Lists.newArrayList();
      for (StreamEvent event : events) {
        out.add(Integer.parseInt(Charsets.UTF_8.decode(event.getBody()).toString()));
      }
      LOG.info("Read events=" + out);
    }
  private void defineRulesForLanguage(
      Context context, String repositoryKey, String repositoryName, String languageKey) {
    NewRepository repository =
        context.createRepository(repositoryKey, languageKey).setName(repositoryName);

    InputStream rulesXml = this.getClass().getResourceAsStream(rulesDefinitionFilePath());
    if (rulesXml != null) {
      RulesDefinitionXmlLoader rulesLoader = new RulesDefinitionXmlLoader();
      rulesLoader.load(repository, rulesXml, Charsets.UTF_8.name());
    }

    repository.done();
  }
 public OutputStreamEventReporter(Builder builder) throws IOException {
   super(builder);
   this.serializer =
       this.closer.register(
           new AvroJsonSerializer<GobblinTrackingEvent>(
               GobblinTrackingEvent.SCHEMA$, new NoopSchemaVersionWriter()));
   this.output = builder.output;
   this.outputBuffer = new ByteArrayOutputStream();
   this.outputBufferPrintStream =
       this.closer.register(new PrintStream(this.outputBuffer, false, Charsets.UTF_8.toString()));
   this.dateFormat =
       DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, Locale.getDefault());
 }
 @VisibleForTesting
 void maybeLoadDefaultLogConfiguration(LogManager logManager)
     throws SecurityException, IOException {
   logManager.reset();
   File logDirectory = new File(caliperDirectory, "log");
   logDirectory.mkdirs();
   FileHandler fileHandler =
       new FileHandler(
           String.format(
               "%s%c%s.%s.log",
               logDirectory.getAbsolutePath(),
               File.separatorChar,
               ISODateTimeFormat.basicDateTimeNoMillis().print(run.startTime()),
               run.id()));
   fileHandler.setEncoding(Charsets.UTF_8.name());
   fileHandler.setFormatter(new SimpleFormatter());
   Logger globalLogger = logManager.getLogger("");
   globalLogger.addHandler(fileHandler);
 }
  private void createTestIndex(File segmentDir) throws Exception {
    List<String> rows =
        Lists.newArrayList(
            "2014102200,host1,10",
            "2014102200,host2,20",
            "2014102200,host3,30",
            "2014102201,host1,10",
            "2014102201,host2,20",
            "2014102201,host3,30",
            "2014102202,host1,10",
            "2014102202,host2,20",
            "2014102202,host3,30");

    StringInputRowParser parser =
        new StringInputRowParser(
            new CSVParseSpec(
                new TimestampSpec("timestamp", "yyyyMMddHH", null),
                new DimensionsSpec(ImmutableList.of("host"), null, null),
                null,
                ImmutableList.of("timestamp", "host", "visited")),
            Charsets.UTF_8.toString());

    AggregatorFactory[] aggregators =
        new AggregatorFactory[] {new LongSumAggregatorFactory("visited_sum", "visited")};

    IncrementalIndex index = null;
    try {
      index = new OnheapIncrementalIndex(0, QueryGranularity.NONE, aggregators, true, 5000);
      for (String line : rows) {
        index.add(parser.parse(line));
      }
      IndexMerger.persist(index, segmentDir, null, new IndexSpec());
    } finally {
      if (index != null) {
        index.close();
      }
    }
  }
  private String getComparator(int i, ByteBuffer bb) {
    String name = comparatorForPosition(i);
    if (name != null) {
      return name;
    }
    if (!dynamic) {
      if (bb.hasRemaining()) {
        return BYTESTYPE.getTypeName();
      } else {
        return null;
      }
    }
    if (bb.hasRemaining()) {
      try {
        int header = getShortLength(bb);
        if ((header & 0x8000) == 0) {

          name = Charsets.UTF_8.newDecoder().decode(getBytes(bb, header).duplicate()).toString();
        } else {
          byte a = (byte) (header & 0xFF);
          name = aliasToComparatorMapping.get(a);
          if (name == null) {
            a = (byte) Character.toLowerCase((char) a);
            name = aliasToComparatorMapping.get(a);
            if (name != null) {
              name += "(reversed=true)";
            }
          }
        }
      } catch (CharacterCodingException e) {
        throw new RuntimeException(e);
      }
    }
    if ((name != null) && (name.length() == 0)) {
      name = null;
    }
    return name;
  }
  @Override
  public void setModels(final CatalogWizardState state) {
    final Design design = new Design();

    design.exportAsCsvLink.setCaptionAsHtml(true);
    try {
      design.exportAsCsvLink.setResource(
          new ExternalResource(
              "/catalog_wizard_export/csv/"
                  + state.getFeatureSet().getSelectedAsUrlEncodedString()
                  + "/"
                  + URLEncoder.encode(
                          state.getFeatureSet().getExportFileBaseName(), Charsets.UTF_8.name())
                      .replace("+", "%20")
                  + ".csv"));
    } catch (final UnsupportedEncodingException e) {
      throw new IllegalStateException(e);
    }
    design.exportAsCsvLink.setTargetName("_blank");
    design.featureSetLayout.addComponent(
        new WizardFeatureSetLayout(Optional.absent(), _getEventBus(), state));

    setCompositionRoot(design);
  }
  @Override
  public String atomBuilder(final Upload upload) {
    // create atom xml metadata - create object first, then convert with
    // xstream

    final Metadata metadata = upload.getMetadata();
    final VideoEntry videoEntry = new VideoEntry();
    videoEntry.mediaGroup.category = new ArrayList<>(1);
    videoEntry.mediaGroup.category.add(metadata.getCategory().toCategory());
    videoEntry.mediaGroup.license = metadata.getLicense().getMetaIdentifier();
    videoEntry.mediaGroup.title = metadata.getTitle();
    videoEntry.mediaGroup.description = metadata.getDescription();
    videoEntry.mediaGroup.keywords =
        Joiner.on(TagParser.TAG_DELIMITER)
            .skipNulls()
            .join(TagParser.parse(metadata.getKeywords()));
    final Permissions permissions = upload.getPermissions();

    if (Visibility.PRIVATE == permissions.getVisibility()
        || Visibility.SCHEDULED == permissions.getVisibility()) {
      videoEntry.mediaGroup.ytPrivate = new Object();
    }

    videoEntry.accessControl.add(
        new YoutubeAccessControl(
            "embed", PermissionStringConverter.convertBoolean(permissions.isEmbed())));
    videoEntry.accessControl.add(
        new YoutubeAccessControl(
            "rate", PermissionStringConverter.convertBoolean(permissions.isRate())));
    videoEntry.accessControl.add(
        new YoutubeAccessControl(
            "commentVote", PermissionStringConverter.convertBoolean(permissions.isCommentvote())));
    videoEntry.accessControl.add(
        new YoutubeAccessControl(
            "comment",
            PermissionStringConverter.convertInteger(permissions.getComment().ordinal())));
    videoEntry.accessControl.add(
        new YoutubeAccessControl(
            "list",
            PermissionStringConverter.convertBoolean(
                Visibility.PUBLIC == permissions.getVisibility())));

    // convert metadata with xstream
    final XStream xStream =
        new XStream(
            new DomDriver(Charsets.UTF_8.name()) {
              @Override
              public HierarchicalStreamWriter createWriter(final Writer out) {
                return new PrettyPrintWriter(out) {
                  boolean isCDATA;

                  @Override
                  public void startNode(
                      final String name, @SuppressWarnings("rawtypes") final Class clazz) {
                    super.startNode(name, clazz);
                    isCDATA =
                        "media:description".equals(name)
                            || "media:keywords".equals(name)
                            || "media:title".equals(name);
                  }

                  @Override
                  protected void writeText(final QuickWriter writer, String text) {
                    final String tmpText = Strings.nullToEmpty(text);
                    text = "null".equals(tmpText) ? "" : tmpText;
                    if (isCDATA) {
                      writer.write("<![CDATA[");
                      writer.write(text);
                      writer.write("]]>");
                    } else {
                      super.writeText(writer, text);
                    }
                  }
                };
              }
            });
    xStream.autodetectAnnotations(true);

    return String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>%s", xStream.toXML(videoEntry));
  }
/** @author jsgroth */
final class SimpleStringTermIteratorImpl implements SimpleStringTermIterator {
  private static final Logger log = Logger.getLogger(SimpleStringTermIteratorImpl.class);

  private static final int BUFFER_SIZE = 8192;

  private final byte[] buffer;
  private int bufferLen;
  private long bufferOffset;
  private int bufferPtr;

  private final String docsFilename;
  private ImmutableBTreeIndex.Reader<String, LongPair> index;
  private final File indexFile;

  private final CharsetDecoder decoder = Charsets.UTF_8.newDecoder();

  private final SharedReference<MMapBuffer> file;
  private final DirectMemory memory;

  private byte[] lastTermBytes = new byte[100];
  private ByteBuffer lastTermByteBuffer = ByteBuffer.wrap(lastTermBytes);
  private int lastTermLength = 0;
  private long lastTermOffset = 0L;
  private int lastTermDocFreq = 0;
  private String lastString = null;

  private boolean done = false;
  private boolean bufferNext = false;
  private boolean closed = false;

  SimpleStringTermIteratorImpl(
      MapCache mapCache, String filename, String docsFilename, String indexFilename)
      throws IOException {
    buffer = new byte[BUFFER_SIZE];

    this.docsFilename = docsFilename;
    final CachedFile cf = CachedFile.create(indexFilename);
    if (cf.exists()) {
      indexFile = cf.loadDirectory();
    } else {
      indexFile = null;
    }

    file = mapCache.copyOrOpen(filename);
    memory = file.get().memory();
    done = false;
    bufferLen = 0;
    bufferOffset = 0L;
    bufferPtr = 0;
  }

  @Override
  public void reset(String term) {
    try {
      internalReset(term);
    } catch (IOException e) {
      close();
      throw new RuntimeException(e);
    }
  }

  private void internalReset(String term) throws IOException {
    if (indexFile != null) {
      if (index == null) {
        index =
            new ImmutableBTreeIndex.Reader<String, LongPair>(
                indexFile, new StringSerializer(), new LongPairSerializer(), false);
      }
      Generation.Entry<String, LongPair> e = index.floor(term);
      if (e == null) {
        e = index.first();
      }
      lastTermBytes = e.getKey().getBytes(Charsets.UTF_8);
      lastTermByteBuffer = ByteBuffer.wrap(lastTermBytes);
      lastTermLength = lastTermBytes.length;
      lastString = null;
      final LongPair p = e.getValue();
      refillBuffer(p.getFirst());
      lastTermOffset = p.getSecond();
      lastTermDocFreq = (int) readVLong();
      done = false;

      while (decoder
                  .decode((ByteBuffer) lastTermByteBuffer.position(0).limit(lastTermLength))
                  .toString()
                  .compareTo(term)
              < 0
          && next()) {}
      bufferNext = true;
    } else {
      lastTermLength = 0;
      lastTermOffset = 0L;
      lastTermDocFreq = 0;
      lastString = null;

      bufferLen = 0;
      bufferOffset = 0L;
      bufferPtr = 0;

      done = false;

      while (next()
          && new String(lastTermBytes, 0, lastTermLength, Charsets.UTF_8).compareTo(term) < 0) {}
      bufferNext = true;
    }
  }

  @Override
  public String term() {
    if (lastString == null) {
      try {
        lastString =
            decoder
                .decode((ByteBuffer) lastTermByteBuffer.position(0).limit(lastTermLength))
                .toString();
      } catch (CharacterCodingException e) {
        throw new RuntimeException(e);
      }
    }
    return lastString;
  }

  @Override
  public byte[] termStringBytes() {
    return lastTermBytes;
  }

  @Override
  public int termStringLength() {
    return lastTermLength;
  }

  @Override
  public boolean next() {
    try {
      return internalNext();
    } catch (IOException e) {
      close();
      throw new RuntimeException(e);
    }
  }

  private boolean internalNext() throws IOException {
    if (done) return false;
    if (bufferNext) {
      bufferNext = false;
      return true;
    }

    final int firstByte = read();
    if (firstByte == -1) {
      done = true;
      return false;
    }

    final int removeLen = (int) readVLong(firstByte);
    final int newLen = (int) readVLong();

    ensureCapacity(lastTermLength - removeLen + newLen);
    readFully(lastTermBytes, lastTermLength - removeLen, newLen);
    lastTermLength = lastTermLength - removeLen + newLen;
    lastString = null;

    final long offsetDelta = readVLong();
    lastTermOffset += offsetDelta;

    lastTermDocFreq = (int) readVLong();

    return true;
  }

  private void ensureCapacity(int len) {
    // TODO is > sufficient here? I think yes, verify later
    if (len >= lastTermBytes.length) {
      lastTermBytes = Arrays.copyOf(lastTermBytes, Math.max(len, 2 * lastTermBytes.length));
      lastTermByteBuffer = ByteBuffer.wrap(lastTermBytes);
    }
  }

  @Override
  public int docFreq() {
    return lastTermDocFreq;
  }

  @Override
  public void close() {
    if (!closed) {
      try {
        if (index != null) {
          index.close();
        }
      } catch (IOException e) {
        log.error("error closing index", e);
      }
      try {
        file.close();
      } catch (IOException e) {
        log.error("error closing file", e);
      }
      closed = true;
    }
  }

  @Override
  public String getFilename() {
    return docsFilename;
  }

  @Override
  public long getOffset() {
    return lastTermOffset;
  }

  private int read() throws IOException {
    if (bufferPtr == bufferLen) {
      refillBuffer(bufferOffset + bufferLen);
      if (bufferLen == 0) return -1;
    }
    return buffer[bufferPtr++] & 0xFF;
  }

  private void readFully(final byte[] b, int off, int len) throws IOException {
    while (true) {
      final int available = bufferLen - bufferPtr;
      if (available >= len) {
        System.arraycopy(buffer, bufferPtr, b, off, len);
        bufferPtr += len;
        return;
      } else {
        System.arraycopy(buffer, bufferPtr, b, off, available);
        off += available;
        len -= available;
        refillBuffer(bufferOffset + bufferLen);
      }
    }
  }

  private void refillBuffer(final long offset) throws IOException {
    bufferLen = (int) Math.min(buffer.length, memory.length() - offset);
    if (bufferLen > 0) {
      memory.getBytes(offset, buffer, 0, bufferLen);
    }
    bufferOffset = offset;
    bufferPtr = 0;
  }

  private long readVLong(int b) throws IOException {
    long ret = 0L;
    int shift = 0;
    do {
      ret |= ((b & 0x7F) << shift);
      if (b < 0x80) return ret;
      shift += 7;
      b = read();
    } while (true);
  }

  private long readVLong() throws IOException {
    long ret = 0L;
    int shift = 0;
    do {
      int b = read();
      ret |= ((b & 0x7F) << shift);
      if (b < 0x80) return ret;
      shift += 7;
    } while (true);
  }
}
 public static String encode(final String text) throws EncoderException {
   return BCODEC.encode(text, Charsets.UTF_8.name());
 }
Exemple #24
0
@Beta
@GwtCompatible
@Immutable
public final class MediaType {
  private static final String CHARSET_ATTRIBUTE = "charset";
  private static final ImmutableListMultimap<String, String> UTF_8_CONSTANT_PARAMETERS =
      ImmutableListMultimap.of("charset", Ascii.toLowerCase(Charsets.UTF_8.name()));
  private static final CharMatcher TOKEN_MATCHER =
      CharMatcher.ASCII
          .and(CharMatcher.JAVA_ISO_CONTROL.negate())
          .and(CharMatcher.isNot(' '))
          .and(CharMatcher.noneOf("()<>@,;:\\\"/[]?="));
  private static final CharMatcher QUOTED_TEXT_MATCHER =
      CharMatcher.ASCII.and(CharMatcher.noneOf("\"\\\r"));
  private static final CharMatcher LINEAR_WHITE_SPACE = CharMatcher.anyOf(" \t\r\n");
  private static final String APPLICATION_TYPE = "application";
  private static final String AUDIO_TYPE = "audio";
  private static final String IMAGE_TYPE = "image";
  private static final String TEXT_TYPE = "text";
  private static final String VIDEO_TYPE = "video";
  private static final String WILDCARD = "*";
  private static final Map<MediaType, MediaType> KNOWN_TYPES = Maps.newHashMap();

  private static MediaType createConstant(String type, String subtype) {
    return addKnownType(new MediaType(type, subtype, ImmutableListMultimap.of()));
  }

  private static MediaType createConstantUtf8(String type, String subtype) {
    return addKnownType(new MediaType(type, subtype, UTF_8_CONSTANT_PARAMETERS));
  }

  private static MediaType addKnownType(MediaType mediaType) {
    KNOWN_TYPES.put(mediaType, mediaType);
    return mediaType;
  }

  public static final MediaType ANY_TYPE = createConstant("*", "*");
  public static final MediaType ANY_TEXT_TYPE = createConstant("text", "*");
  public static final MediaType ANY_IMAGE_TYPE = createConstant("image", "*");
  public static final MediaType ANY_AUDIO_TYPE = createConstant("audio", "*");
  public static final MediaType ANY_VIDEO_TYPE = createConstant("video", "*");
  public static final MediaType ANY_APPLICATION_TYPE = createConstant("application", "*");
  public static final MediaType CACHE_MANIFEST_UTF_8 = createConstantUtf8("text", "cache-manifest");
  public static final MediaType CSS_UTF_8 = createConstantUtf8("text", "css");
  public static final MediaType CSV_UTF_8 = createConstantUtf8("text", "csv");
  public static final MediaType HTML_UTF_8 = createConstantUtf8("text", "html");
  public static final MediaType I_CALENDAR_UTF_8 = createConstantUtf8("text", "calendar");
  public static final MediaType PLAIN_TEXT_UTF_8 = createConstantUtf8("text", "plain");
  public static final MediaType TEXT_JAVASCRIPT_UTF_8 = createConstantUtf8("text", "javascript");
  public static final MediaType TSV_UTF_8 = createConstantUtf8("text", "tab-separated-values");
  public static final MediaType VCARD_UTF_8 = createConstantUtf8("text", "vcard");
  public static final MediaType WML_UTF_8 = createConstantUtf8("text", "vnd.wap.wml");
  public static final MediaType XML_UTF_8 = createConstantUtf8("text", "xml");
  public static final MediaType BMP = createConstant("image", "bmp");
  public static final MediaType CRW = createConstant("image", "x-canon-crw");
  public static final MediaType GIF = createConstant("image", "gif");
  public static final MediaType ICO = createConstant("image", "vnd.microsoft.icon");
  public static final MediaType JPEG = createConstant("image", "jpeg");
  public static final MediaType PNG = createConstant("image", "png");
  public static final MediaType PSD = createConstant("image", "vnd.adobe.photoshop");
  public static final MediaType SVG_UTF_8 = createConstantUtf8("image", "svg+xml");
  public static final MediaType TIFF = createConstant("image", "tiff");
  public static final MediaType WEBP = createConstant("image", "webp");
  public static final MediaType MP4_AUDIO = createConstant("audio", "mp4");
  public static final MediaType MPEG_AUDIO = createConstant("audio", "mpeg");
  public static final MediaType OGG_AUDIO = createConstant("audio", "ogg");
  public static final MediaType WEBM_AUDIO = createConstant("audio", "webm");
  public static final MediaType MP4_VIDEO = createConstant("video", "mp4");
  public static final MediaType MPEG_VIDEO = createConstant("video", "mpeg");
  public static final MediaType OGG_VIDEO = createConstant("video", "ogg");
  public static final MediaType QUICKTIME = createConstant("video", "quicktime");
  public static final MediaType WEBM_VIDEO = createConstant("video", "webm");
  public static final MediaType WMV = createConstant("video", "x-ms-wmv");
  public static final MediaType APPLICATION_XML_UTF_8 = createConstantUtf8("application", "xml");
  public static final MediaType ATOM_UTF_8 = createConstantUtf8("application", "atom+xml");
  public static final MediaType BZIP2 = createConstant("application", "x-bzip2");
  public static final MediaType EOT = createConstant("application", "vnd.ms-fontobject");
  public static final MediaType EPUB = createConstant("application", "epub+zip");
  public static final MediaType FORM_DATA = createConstant("application", "x-www-form-urlencoded");
  public static final MediaType KEY_ARCHIVE = createConstant("application", "pkcs12");
  public static final MediaType APPLICATION_BINARY = createConstant("application", "binary");
  public static final MediaType GZIP = createConstant("application", "x-gzip");
  public static final MediaType JAVASCRIPT_UTF_8 = createConstantUtf8("application", "javascript");
  public static final MediaType JSON_UTF_8 = createConstantUtf8("application", "json");
  public static final MediaType KML = createConstant("application", "vnd.google-earth.kml+xml");
  public static final MediaType KMZ = createConstant("application", "vnd.google-earth.kmz");
  public static final MediaType MBOX = createConstant("application", "mbox");
  public static final MediaType MICROSOFT_EXCEL = createConstant("application", "vnd.ms-excel");
  public static final MediaType MICROSOFT_POWERPOINT =
      createConstant("application", "vnd.ms-powerpoint");
  public static final MediaType MICROSOFT_WORD = createConstant("application", "msword");
  public static final MediaType OCTET_STREAM = createConstant("application", "octet-stream");
  public static final MediaType OGG_CONTAINER = createConstant("application", "ogg");
  public static final MediaType OOXML_DOCUMENT =
      createConstant("application", "vnd.openxmlformats-officedocument.wordprocessingml.document");
  public static final MediaType OOXML_PRESENTATION =
      createConstant(
          "application", "vnd.openxmlformats-officedocument.presentationml.presentation");
  public static final MediaType OOXML_SHEET =
      createConstant("application", "vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  public static final MediaType OPENDOCUMENT_GRAPHICS =
      createConstant("application", "vnd.oasis.opendocument.graphics");
  public static final MediaType OPENDOCUMENT_PRESENTATION =
      createConstant("application", "vnd.oasis.opendocument.presentation");
  public static final MediaType OPENDOCUMENT_SPREADSHEET =
      createConstant("application", "vnd.oasis.opendocument.spreadsheet");
  public static final MediaType OPENDOCUMENT_TEXT =
      createConstant("application", "vnd.oasis.opendocument.text");
  public static final MediaType PDF = createConstant("application", "pdf");
  public static final MediaType POSTSCRIPT = createConstant("application", "postscript");
  public static final MediaType PROTOBUF = createConstant("application", "protobuf");
  public static final MediaType RDF_XML_UTF_8 = createConstantUtf8("application", "rdf+xml");
  public static final MediaType RTF_UTF_8 = createConstantUtf8("application", "rtf");
  public static final MediaType SFNT = createConstant("application", "font-sfnt");
  public static final MediaType SHOCKWAVE_FLASH =
      createConstant("application", "x-shockwave-flash");
  public static final MediaType SKETCHUP = createConstant("application", "vnd.sketchup.skp");
  public static final MediaType TAR = createConstant("application", "x-tar");
  public static final MediaType WOFF = createConstant("application", "font-woff");
  public static final MediaType XHTML_UTF_8 = createConstantUtf8("application", "xhtml+xml");
  public static final MediaType XRD_UTF_8 = createConstantUtf8("application", "xrd+xml");
  public static final MediaType ZIP = createConstant("application", "zip");
  private final String type;
  private final String subtype;
  private final ImmutableListMultimap<String, String> parameters;

  private MediaType(String type, String subtype, ImmutableListMultimap<String, String> parameters) {
    this.type = type;
    this.subtype = subtype;
    this.parameters = parameters;
  }

  public String type() {
    return this.type;
  }

  public String subtype() {
    return this.subtype;
  }

  public ImmutableListMultimap<String, String> parameters() {
    return this.parameters;
  }

  private Map<String, ImmutableMultiset<String>> parametersAsMap() {
    Maps.transformValues(
        this.parameters.asMap(),
        new Function() {
          public ImmutableMultiset<String> apply(Collection<String> input) {
            return ImmutableMultiset.copyOf(input);
          }
        });
  }

  public Optional<Charset> charset() {
    ImmutableSet<String> charsetValues = ImmutableSet.copyOf(this.parameters.get("charset"));
    switch (charsetValues.size()) {
      case 0:
        return Optional.absent();
      case 1:
        return Optional.of(Charset.forName((String) Iterables.getOnlyElement(charsetValues)));
    }
    throw new IllegalStateException("Multiple charset values defined: " + charsetValues);
  }

  public MediaType withoutParameters() {
    return this.parameters.isEmpty() ? this : create(this.type, this.subtype);
  }

  public MediaType withParameters(Multimap<String, String> parameters) {
    return create(this.type, this.subtype, parameters);
  }

  public MediaType withParameter(String attribute, String value) {
    Preconditions.checkNotNull(attribute);
    Preconditions.checkNotNull(value);
    String normalizedAttribute = normalizeToken(attribute);
    ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
    for (Map.Entry<String, String> entry : this.parameters.entries()) {
      String key = (String) entry.getKey();
      if (!normalizedAttribute.equals(key)) {
        builder.put(key, entry.getValue());
      }
    }
    builder.put(normalizedAttribute, normalizeParameterValue(normalizedAttribute, value));
    MediaType mediaType = new MediaType(this.type, this.subtype, builder.build());

    return (MediaType) Objects.firstNonNull(KNOWN_TYPES.get(mediaType), mediaType);
  }

  public MediaType withCharset(Charset charset) {
    Preconditions.checkNotNull(charset);
    return withParameter("charset", charset.name());
  }

  public boolean hasWildcard() {
    return ("*".equals(this.type)) || ("*".equals(this.subtype));
  }

  public boolean is(MediaType mediaTypeRange) {
    return ((mediaTypeRange.type.equals("*")) || (mediaTypeRange.type.equals(this.type)))
        && ((mediaTypeRange.subtype.equals("*")) || (mediaTypeRange.subtype.equals(this.subtype)))
        && (this.parameters.entries().containsAll(mediaTypeRange.parameters.entries()));
  }

  public static MediaType create(String type, String subtype) {
    return create(type, subtype, ImmutableListMultimap.of());
  }

  static MediaType createApplicationType(String subtype) {
    return create("application", subtype);
  }

  static MediaType createAudioType(String subtype) {
    return create("audio", subtype);
  }

  static MediaType createImageType(String subtype) {
    return create("image", subtype);
  }

  static MediaType createTextType(String subtype) {
    return create("text", subtype);
  }

  static MediaType createVideoType(String subtype) {
    return create("video", subtype);
  }

  private static MediaType create(
      String type, String subtype, Multimap<String, String> parameters) {
    Preconditions.checkNotNull(type);
    Preconditions.checkNotNull(subtype);
    Preconditions.checkNotNull(parameters);
    String normalizedType = normalizeToken(type);
    String normalizedSubtype = normalizeToken(subtype);
    Preconditions.checkArgument(
        (!"*".equals(normalizedType)) || ("*".equals(normalizedSubtype)),
        "A wildcard type cannot be used with a non-wildcard subtype");

    ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
    for (Map.Entry<String, String> entry : parameters.entries()) {
      String attribute = normalizeToken((String) entry.getKey());
      builder.put(attribute, normalizeParameterValue(attribute, (String) entry.getValue()));
    }
    MediaType mediaType = new MediaType(normalizedType, normalizedSubtype, builder.build());

    return (MediaType) Objects.firstNonNull(KNOWN_TYPES.get(mediaType), mediaType);
  }

  private static String normalizeToken(String token) {
    Preconditions.checkArgument(TOKEN_MATCHER.matchesAllOf(token));
    return Ascii.toLowerCase(token);
  }

  private static String normalizeParameterValue(String attribute, String value) {
    return "charset".equals(attribute) ? Ascii.toLowerCase(value) : value;
  }

  public static MediaType parse(String input) {
    Preconditions.checkNotNull(input);
    Tokenizer tokenizer = new Tokenizer(input);
    try {
      String type = tokenizer.consumeToken(TOKEN_MATCHER);
      tokenizer.consumeCharacter('/');
      String subtype = tokenizer.consumeToken(TOKEN_MATCHER);
      ImmutableListMultimap.Builder<String, String> parameters = ImmutableListMultimap.builder();
      while (tokenizer.hasMore()) {
        tokenizer.consumeCharacter(';');
        tokenizer.consumeTokenIfPresent(LINEAR_WHITE_SPACE);
        String attribute = tokenizer.consumeToken(TOKEN_MATCHER);
        tokenizer.consumeCharacter('=');
        String value;
        if ('"' == tokenizer.previewChar()) {
          tokenizer.consumeCharacter('"');
          StringBuilder valueBuilder = new StringBuilder();
          while ('"' != tokenizer.previewChar()) {
            if ('\\' == tokenizer.previewChar()) {
              tokenizer.consumeCharacter('\\');
              valueBuilder.append(tokenizer.consumeCharacter(CharMatcher.ASCII));
            } else {
              valueBuilder.append(tokenizer.consumeToken(QUOTED_TEXT_MATCHER));
            }
          }
          String value = valueBuilder.toString();
          tokenizer.consumeCharacter('"');
        } else {
          value = tokenizer.consumeToken(TOKEN_MATCHER);
        }
        parameters.put(attribute, value);
      }
      return create(type, subtype, parameters.build());
    } catch (IllegalStateException e) {
      throw new IllegalArgumentException("Could not parse '" + input + "'", e);
    }
  }

  private static final class Tokenizer {
    final String input;
    int position = 0;

    Tokenizer(String input) {
      this.input = input;
    }

    String consumeTokenIfPresent(CharMatcher matcher) {
      Preconditions.checkState(hasMore());
      int startPosition = this.position;
      this.position = matcher.negate().indexIn(this.input, startPosition);
      return hasMore()
          ? this.input.substring(startPosition, this.position)
          : this.input.substring(startPosition);
    }

    String consumeToken(CharMatcher matcher) {
      int startPosition = this.position;
      String token = consumeTokenIfPresent(matcher);
      Preconditions.checkState(this.position != startPosition);
      return token;
    }

    char consumeCharacter(CharMatcher matcher) {
      Preconditions.checkState(hasMore());
      char c = previewChar();
      Preconditions.checkState(matcher.matches(c));
      this.position += 1;
      return c;
    }

    char consumeCharacter(char c) {
      Preconditions.checkState(hasMore());
      Preconditions.checkState(previewChar() == c);
      this.position += 1;
      return c;
    }

    char previewChar() {
      Preconditions.checkState(hasMore());
      return this.input.charAt(this.position);
    }

    boolean hasMore() {
      return (this.position >= 0) && (this.position < this.input.length());
    }
  }

  public boolean equals(@Nullable Object obj) {
    if (obj == this) {
      return true;
    }
    if ((obj instanceof MediaType)) {
      MediaType that = (MediaType) obj;
      return (this.type.equals(that.type))
          && (this.subtype.equals(that.subtype))
          && (parametersAsMap().equals(that.parametersAsMap()));
    }
    return false;
  }

  public int hashCode() {
    return Objects.hashCode(new Object[] {this.type, this.subtype, parametersAsMap()});
  }

  private static final Joiner.MapJoiner PARAMETER_JOINER =
      Joiner.on("; ").withKeyValueSeparator("=");

  public String toString() {
    StringBuilder builder = new StringBuilder().append(this.type).append('/').append(this.subtype);
    if (!this.parameters.isEmpty()) {
      builder.append("; ");
      Multimap<String, String> quotedParameters =
          Multimaps.transformValues(
              this.parameters,
              new Function() {
                public String apply(String value) {
                  return MediaType.TOKEN_MATCHER.matchesAllOf(value)
                      ? value
                      : MediaType.escapeAndQuote(value);
                }
              });
      PARAMETER_JOINER.appendTo(builder, quotedParameters.entries());
    }
    return builder.toString();
  }

  private static String escapeAndQuote(String value) {
    StringBuilder escaped = new StringBuilder(value.length() + 16).append('"');
    for (char ch : value.toCharArray()) {
      if ((ch == '\r') || (ch == '\\') || (ch == '"')) {
        escaped.append('\\');
      }
      escaped.append(ch);
    }
    return '"';
  }
}