com.admc.jcreole.marker.BufferMarker.java Source code

Java tutorial

Introduction

Here is the source code for com.admc.jcreole.marker.BufferMarker.java

Source

/*
 * Copyright 2011 Axis Data Management Corp.
 *
 * 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.admc.jcreole.marker;

import org.apache.commons.lang.StringUtils;

/**
 * Inserts CSS class names into the parser output.
 *
 * @author Blaine Simpson (blaine dot simpson at admc dot com)
 * @since 1.1
 */
abstract public class BufferMarker implements Comparable<BufferMarker> {
    /* Undecided about whether to store source location offset/line/col.
     * Would have to complicate parser code by passiing around the
     * originating non-terminals all over the place. */
    protected int offset = -1;
    protected int id = -1;
    protected StringBuilder targetSb;
    public static final char markerChar = '\u001a';
    protected boolean applied;

    public String toString() {
        return getIdString() + '@' + offset;
    }

    public boolean equals(Object o) {
        if (o == null)
            return false;
        if (!(o instanceof BufferMarker))
            return false;
        return compareTo((BufferMarker) o) == 0;
    }

    public int compareTo(BufferMarker other) {
        if (this == other)
            return 0;
        if (offset < 0 && other.offset < 0)
            return Integer.valueOf(id).compareTo(Integer.valueOf(other.id));
        return Integer.valueOf(offset).compareTo(Integer.valueOf(other.offset));
    }

    protected BufferMarker(int id) {
        this.id = id;
        if (id < 0 || id > 0xFFFF)
            throw new IllegalArgumentException("Id is not between 0 and 0xFFFF inclusive: " + id);
    }

    public String getIdString() {
        return String.format("%04X", id);
    }

    public String getMarkerString() {
        return Character.toString(markerChar) + getIdString();
    }

    public int getOffset() {
        return offset;
    }

    /**
     * Confirms that a marker for this inserter exists at the indicated point
     * in the supplied StringBuilder.
     *
     * @throws IllegalStateException if marker for this CssClassInsert not
     *         found at the indicated location.
     */
    public void validate() {
        if (targetSb == null || offset < 1)
            throw new IllegalStateException("targetSb or offset not initialized");
        if (targetSb.length() < offset + 4)
            throw new IllegalStateException("StringBuilder not long enough to contain marker at " + offset);
        if (targetSb.charAt(offset) != '\u001a')
            throw new IllegalStateException("Missing binary SUB char at offset " + offset);
        if (!targetSb.substring(offset + 1, offset + 5).equals(getIdString()))
            throw new IllegalStateException("Marker ID mismatch.  Expected " + getIdString() + " but is '"
                    + targetSb.substring(offset + 1, offset + 5) + "'");
    }

    public void setContext(StringBuilder targetSb, int offset) {
        this.targetSb = targetSb;
        this.offset = offset;
        validate();
    }

    /**
     * Removes the single character at the indicated point.
     * Some subclasses will need to do more than this to update the buffer.
     */
    public void updateBuffer() {
        if (applied)
            throw new IllegalStateException("This marker already applied: " + this);
        validate(); // Rechecking since contents of the targetSb could easily
                    // have been shifted since setContext was called.
        targetSb.delete(offset, offset + 5);
    }
}