001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.html;
014
015import java.util.*;
016import java.util.concurrent.*;
017
018import org.apache.juneau.*;
019import org.apache.juneau.annotation.*;
020import org.apache.juneau.collections.*;
021import org.apache.juneau.parser.*;
022import org.apache.juneau.xml.*;
023
024/**
025 * Parses text generated by the {@link HtmlSerializer} class back into a POJO model.
026 *
027 * <h5 class='topic'>Media types</h5>
028 *
029 * Handles <c>Content-Type</c> types:  <bc>text/html</bc>
030 *
031 * <h5 class='topic'>Description</h5>
032 *
033 * See the {@link HtmlSerializer} class for a description of the HTML generated.
034 * <p>
035 * This class is used primarily for automated testing of the {@link HtmlSerializer} class.
036 */
037@ConfigurableContext
038public class HtmlParser extends XmlParser implements HtmlMetaProvider, HtmlCommon {
039
040   //-------------------------------------------------------------------------------------------------------------------
041   // Configurable properties
042   //-------------------------------------------------------------------------------------------------------------------
043
044   static final String PREFIX = "HtmlParser";
045
046   //-------------------------------------------------------------------------------------------------------------------
047   // Predefined instances
048   //-------------------------------------------------------------------------------------------------------------------
049
050   /** Default parser, all default settings.*/
051   public static final HtmlParser DEFAULT = new HtmlParser(PropertyStore.DEFAULT);
052
053
054   //-------------------------------------------------------------------------------------------------------------------
055   // Instance
056   //-------------------------------------------------------------------------------------------------------------------
057
058   private final Map<ClassMeta<?>,HtmlClassMeta> htmlClassMetas = new ConcurrentHashMap<>();
059   private final Map<BeanPropertyMeta,HtmlBeanPropertyMeta> htmlBeanPropertyMetas = new ConcurrentHashMap<>();
060
061   /**
062    * Constructor.
063    *
064    * @param ps The property store containing all the settings for this object.
065    */
066   public HtmlParser(PropertyStore ps) {
067      super(ps, "text/html", "text/html+stripped");
068   }
069
070   @Override /* Context */
071   public HtmlParserBuilder builder() {
072      return new HtmlParserBuilder(getPropertyStore());
073   }
074
075   /**
076    * Instantiates a new clean-slate {@link HtmlParserBuilder} object.
077    *
078    * <p>
079    * This is equivalent to simply calling <code><jk>new</jk> HtmlParserBuilder()</code>.
080    *
081    * <p>
082    * Note that this method creates a builder initialized to all default settings, whereas {@link #builder()} copies
083    * the settings of the object called on.
084    *
085    * @return A new {@link HtmlParserBuilder} object.
086    */
087   public static HtmlParserBuilder create() {
088      return new HtmlParserBuilder();
089   }
090
091   @Override /* Parser */
092   public HtmlParserSession createSession() {
093      return createSession(createDefaultSessionArgs());
094   }
095
096   @Override /* Parser */
097   public HtmlParserSession createSession(ParserSessionArgs args) {
098      return new HtmlParserSession(this, args);
099   }
100
101   //-----------------------------------------------------------------------------------------------------------------
102   // Extended metadata
103   //-----------------------------------------------------------------------------------------------------------------
104
105   @Override /* HtmlMetaProvider */
106   public HtmlClassMeta getHtmlClassMeta(ClassMeta<?> cm) {
107      HtmlClassMeta m = htmlClassMetas.get(cm);
108      if (m == null) {
109         m = new HtmlClassMeta(cm, this);
110         htmlClassMetas.put(cm, m);
111      }
112      return m;
113   }
114
115   @Override /* HtmlMetaProvider */
116   public HtmlBeanPropertyMeta getHtmlBeanPropertyMeta(BeanPropertyMeta bpm) {
117      if (bpm == null)
118         return HtmlBeanPropertyMeta.DEFAULT;
119      HtmlBeanPropertyMeta m = htmlBeanPropertyMetas.get(bpm);
120      if (m == null) {
121         m = new HtmlBeanPropertyMeta(bpm.getDelegateFor(), this);
122         htmlBeanPropertyMetas.put(bpm, m);
123      }
124      return m;
125   }
126
127   //-----------------------------------------------------------------------------------------------------------------
128   // Other methods
129   //-----------------------------------------------------------------------------------------------------------------
130
131   @Override /* Context */
132   public OMap toMap() {
133      return super.toMap()
134         .a("HtmlParser", new DefaultFilteringOMap());
135   }
136}