| /* |
| * Copyright (C) 2010 Google Inc. |
| * |
| * 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 com.google.streamhtmlparser.impl; |
| |
| import com.google.common.base.Preconditions; |
| |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| /** |
| * A very simple representation of the parser internal state. The state |
| * contains a small integer identifier (from 1 to 255) to allow for |
| * the implementation of a simple finite state machine. The name is |
| * purely informational. |
| * |
| * <p>In order to eliminate the possibility that different states have |
| * the same identifier, this class manages the idenitifiers themselves. |
| * The HTML and Javascript parser states are managed elsewhere in different |
| * "namespaces" hence will not clash and there is no current need for this |
| * class to disambiguate them further. |
| * |
| * <p>The methods to create new <code>InternalState</code> instances are |
| * package-scope only as they are only needed by <code>HtmlParserImpl</code> |
| * and <code>JavascriptParserImpl</code>. |
| */ |
| class InternalState { |
| |
| // An InternalState to represent an error condition for all parsers. |
| static final InternalState INTERNAL_ERROR_STATE = new InternalState(); |
| |
| // MAX_ID and FIRST_ID are only used for asserts against developer error. |
| private static final int MAX_ID = 255; |
| private static final int FIRST_ID = 1; |
| |
| private static AtomicInteger htmlStates = new AtomicInteger(FIRST_ID); |
| private static AtomicInteger javascriptStates = new AtomicInteger(FIRST_ID); |
| private final String name; |
| private final int id; |
| |
| /** |
| * @param name the {@code String} identifier for this state |
| * @param id the integer identiifer for this state, guaranteed to be unique |
| */ |
| private InternalState(String name, int id) { |
| Preconditions.checkNotNull(name); |
| Preconditions.checkArgument(id >= FIRST_ID); |
| Preconditions.checkArgument(id <= MAX_ID); |
| this.name = name; |
| this.id = id; |
| } |
| |
| /** |
| * Used only for the error state. Bypasses assert checks. |
| */ |
| private InternalState() { |
| name = "InternalStateError"; |
| id = 0; |
| } |
| |
| /** |
| * @return {@code String} name of that state. |
| */ |
| public String getName() { |
| return name; |
| } |
| |
| /** |
| * @return {@code int} id of that state. |
| */ |
| public int getId() { |
| return id; |
| } |
| |
| /** |
| * @return {@code String} representation of that object, the format |
| * may change. |
| */ |
| @Override |
| public String toString() { |
| return String.format("InternalState: Name: %s; Id: %d", name, id); |
| } |
| |
| /** |
| * Obtain a new {@code InternalState} instance for the HTML parser. |
| * |
| * @param name a unique identifier for this state useful during debugging |
| * @return a new {@code InternalState} object |
| */ |
| static InternalState getInstanceHtml(String name) { |
| int htmlStateId = htmlStates.getAndIncrement(); |
| return new InternalState(name, htmlStateId); |
| } |
| |
| /** |
| * Obtain a new <code>InternalState</code> instance for the Javascript parser. |
| * |
| * @param name A unique identifier for this state useful during debugging |
| * @return a new {@code InternalState} object |
| */ |
| static InternalState getInstanceJavascript(String name) { |
| int javascriptStateId = javascriptStates.getAndIncrement(); |
| return new InternalState(name, javascriptStateId); |
| } |
| } |