All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.parser.ParserGroup Maven / Gradle / Ivy

There is a newer version: 9.0.1
Show newest version
// ***************************************************************************************************************************
// * 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.juneau.parser;

import static org.apache.juneau.internal.CollectionUtils.*;

import java.util.*;
import java.util.concurrent.*;

import org.apache.juneau.*;
import org.apache.juneau.http.*;

/**
 * Represents a group of {@link Parser Parsers} that can be looked up by media type.
 *
 * 
Description
* * Provides the following features: *
    *
  • * Finds parsers based on HTTP Content-Type header values. *
  • * Sets common properties on all parsers in a single method call. *
  • * Locks all parsers in a single method call. *
  • * Clones existing groups and all parsers within the group in a single method call. *
* *
Match ordering
* * Parsers are matched against Content-Type strings in the order they exist in this group. * *

* Adding new entries will cause the entries to be prepended to the group. * This allows for previous parsers to be overridden through subsequent calls. * *

* For example, calling g.append(P1.class,P2.class).append(P3.class,P4.class) * will result in the order P3, P4, P1, P2. * *

Example:
*

* // Construct a new parser group builder * ParserGroupBuilder b = ParserGroup.create(); * * // Add some parsers to it * b.append(JsonParser.class, XmlParser.class); * * // Change settings on parsers simultaneously * b.set(BeanContext.BEAN_beansRequireSerializable, true) * .pojoSwaps(CalendarSwap.ISO8601DT.class); * * ParserGroup g = b.build(); * * // Find the appropriate parser by Content-Type * ReaderParser p = (ReaderParser)g.getParser("text/json"); * * // Parse a bean from JSON * String json = "{...}"; * AddressBook addressBook = p.parse(json, AddressBook.class); *

*/ public final class ParserGroup extends BeanContext { /** * An unmodifiable empty parser group. */ public static final ParserGroup EMPTY = create().build(); // Maps Content-Type headers to matches. private final ConcurrentHashMap cache = new ConcurrentHashMap<>(); private final MediaType[] mediaTypes; // List of media types private final List mediaTypesList; private final Parser[] mediaTypeParsers; private final List parsers; /** * Instantiates a new clean-slate {@link ParserGroupBuilder} object. * *

* This is equivalent to simply calling new ParserGroupBuilder(). * * @return A new {@link ParserGroupBuilder} object. */ public static ParserGroupBuilder create() { return new ParserGroupBuilder(); } /** * Returns a builder that's a copy of the settings on this parser group. * * @return A new {@link ParserGroupBuilder} initialized to this group. */ @Override /* Context */ public ParserGroupBuilder builder() { return new ParserGroupBuilder(this); } /** * Constructor. * * @param ps * The modifiable properties that were used to initialize the parsers. * A snapshot of these will be made so that we can clone and modify this group. * @param parsers * The parsers defined in this group. * The order is important because they will be tried in reverse order (e.g. newer first) in which they will be * tried to match against media types. */ public ParserGroup(PropertyStore ps, Parser[] parsers) { super(ps); this.parsers = immutableList(parsers); List lmt = new ArrayList<>(); List l = new ArrayList<>(); for (Parser p : parsers) { for (MediaType m: p.getMediaTypes()) { lmt.add(m); l.add(p); } } this.mediaTypes = lmt.toArray(new MediaType[lmt.size()]); this.mediaTypesList = unmodifiableList(lmt); this.mediaTypeParsers = l.toArray(new Parser[l.size()]); } /** * Searches the group for a parser that can handle the specified Content-Type header value. * *

* The returned object includes both the parser and media type that matched. * * @param contentTypeHeader The HTTP Content-Type header value. * @return The parser and media type that matched the content type header, or null if no match was made. */ public ParserMatch getParserMatch(String contentTypeHeader) { ParserMatch pm = cache.get(contentTypeHeader); if (pm != null) return pm; ContentType ct = ContentType.forString(contentTypeHeader); int match = ct.findMatch(mediaTypes); if (match >= 0) { pm = new ParserMatch(mediaTypes[match], mediaTypeParsers[match]); cache.putIfAbsent(contentTypeHeader, pm); } return cache.get(contentTypeHeader); } /** * Same as {@link #getParserMatch(String)} but matches using a {@link MediaType} instance. * * @param mediaType The HTTP Content-Type header value as a media type. * @return The parser and media type that matched the media type, or null if no match was made. */ public ParserMatch getParserMatch(MediaType mediaType) { return getParserMatch(mediaType.toString()); } /** * Same as {@link #getParserMatch(String)} but returns just the matched parser. * * @param contentTypeHeader The HTTP Content-Type header string. * @return The parser that matched the content type header, or null if no match was made. */ public Parser getParser(String contentTypeHeader) { ParserMatch pm = getParserMatch(contentTypeHeader); return pm == null ? null : pm.getParser(); } /** * Same as {@link #getParserMatch(MediaType)} but returns just the matched parser. * * @param mediaType The HTTP media type. * @return The parser that matched the media type, or null if no match was made. */ public Parser getParser(MediaType mediaType) { ParserMatch pm = getParserMatch(mediaType); return pm == null ? null : pm.getParser(); } /** * Returns the media types that all parsers in this group can handle * *

* Entries are ordered in the same order as the parsers in the group. * * @return An unmodifiable list of media types. */ public List getSupportedMediaTypes() { return mediaTypesList; } /** * Returns the parsers in this group. * * @return An unmodifiable list of parsers in this group. */ public List getParsers() { return parsers; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy