org.xwiki.platform.patchservice.impl.PositionImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.xwiki.platform.patchservice.impl.PositionImpl.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 *
 */
package org.xwiki.platform.patchservice.impl;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xwiki.platform.patchservice.api.Position;
import org.xwiki.platform.patchservice.api.XmlSerializable;

import com.xpn.xwiki.XWikiException;

/**
 * Default implementation for {@link Position}. It uses a [row, column] position mark, with an optional context (text
 * before and after the position).
 * 
 * @see org.xwiki.platform.patchservice.api.Position
 * @version $Id$
 * @since XWikiPlatform 1.3
 */
public class PositionImpl implements Position, XmlSerializable {
    /** The name of the XML element corresponding to position objects. */
    public static final String NODE_NAME = "position";

    /** The name of the XML attribute holding the row number. */
    public static final String ROW_ATTRIBUTE_NAME = "row";

    /** The name of the XML attribute holding the column number. */
    public static final String COLUMN_ATTRIBUTE_NAME = "column";

    /** The name of the XML attribute holding the position's length. Currently not used. */
    public static final String SPAN_ATTRIBUTE_NAME = "span";

    /** The name of the XML attribute holding the context before the position. */
    public static final String BEFORE_ATTRIBUTE_NAME = "before";

    /** The name of the XML attribute holding the context after the position. */
    public static final String AFTER_ATTRIBUTE_NAME = "after";

    /** The newline character used. */
    private static final String SEPARATOR = "\n";

    private String before;

    private String after;

    private int row = -1;

    private int column = -1;

    private int span = -1;

    public PositionImpl() {
        this(0, 0, -1, null, null);
    }

    public PositionImpl(int row, int column) {
        this(row, column, -1);
    }

    public PositionImpl(int row, int column, int span) {
        this(row, column, span, null, null);
    }

    public PositionImpl(int row, int column, String before, String after) {
        this(row, column, -1, before, after);
    }

    public PositionImpl(int row, int column, int span, String before, String after) {
        this.row = row;
        this.column = column;
        this.span = span;
        this.before = before;
        this.after = after;
    }

    /**
     * {@inheritDoc}
     */
    public boolean checkPosition(String text) {
        String[] rows = StringUtils.splitPreserveAllTokens(text, SEPARATOR);
        if (rows != null && ((rows.length > this.row && rows[this.row].length() >= this.column)
                || (rows.length == this.row && this.column == 0))) {
            return (StringUtils.isEmpty(this.before) || getTextBeforePosition(text).endsWith(this.before))
                    && (StringUtils.isEmpty(this.after) || getTextAfterPosition(text).startsWith(this.after));
        }
        return (this.row == 0 || this.row == 1) && this.column == 0 && StringUtils.isEmpty(this.before)
                && StringUtils.isEmpty(this.after);
    }

    /**
     * {@inheritDoc}
     */
    public String getTextBeforePosition(String text) {
        String[] rows = StringUtils.splitPreserveAllTokens(text, SEPARATOR);
        if (ArrayUtils.getLength(rows) <= this.row) {
            return StringUtils.defaultString(StringUtils.join(rows, SEPARATOR)) + (this.row == 0 ? "" : "\n");
        }
        return StringUtils.join(ArrayUtils.subarray(rows, 0, this.row), SEPARATOR)
                + ((this.row > 0) ? SEPARATOR : "") + StringUtils.substring(rows[this.row], 0, this.column);
    }

    /**
     * {@inheritDoc}
     */
    public String getTextAfterPosition(String text) {
        String[] rows = StringUtils.splitPreserveAllTokens(text, SEPARATOR);
        if (ArrayUtils.getLength(rows) <= this.row) {
            return "";
        }
        String textAfter = StringUtils.substring(rows[this.row], this.column)
                + ((this.row + 1 < rows.length) ? SEPARATOR : "")
                + StringUtils.join(ArrayUtils.subarray(rows, this.row + 1, rows.length), SEPARATOR);
        return (this.span <= 0) ? textAfter : StringUtils.substring(textAfter, this.span);
    }

    /**
     * {@inheritDoc}
     */
    public void fromXml(Element e) throws XWikiException {
        this.row = Integer.parseInt(e.getAttribute(ROW_ATTRIBUTE_NAME));
        this.column = Integer.parseInt(e.getAttribute(COLUMN_ATTRIBUTE_NAME));
        if (e.hasAttribute(BEFORE_ATTRIBUTE_NAME)) {
            this.before = e.getAttribute(BEFORE_ATTRIBUTE_NAME);
        }
        if (e.hasAttribute(AFTER_ATTRIBUTE_NAME)) {
            this.after = e.getAttribute(AFTER_ATTRIBUTE_NAME);
        }
        if (e.hasAttribute(SPAN_ATTRIBUTE_NAME)) {
            this.span = Integer.parseInt(e.getAttribute(SPAN_ATTRIBUTE_NAME));
        }
    }

    /**
     * {@inheritDoc}
     */
    public Element toXml(Document doc) throws XWikiException {
        Element xmlNode = doc.createElement(NODE_NAME);
        xmlNode.setAttribute(ROW_ATTRIBUTE_NAME, this.row + "");
        xmlNode.setAttribute(COLUMN_ATTRIBUTE_NAME, this.column + "");
        if (!StringUtils.isEmpty(this.before)) {
            xmlNode.setAttribute(BEFORE_ATTRIBUTE_NAME, this.before);
        }
        if (!StringUtils.isEmpty(this.after)) {
            xmlNode.setAttribute(AFTER_ATTRIBUTE_NAME, this.after);
        }
        if (this.span >= 0) {
            xmlNode.setAttribute(SPAN_ATTRIBUTE_NAME, this.span + "");
        }
        return xmlNode;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object other) {
        try {
            PositionImpl that = (PositionImpl) other;
            return (that.row == this.row) && that.column == this.column
                    && StringUtils.defaultString(that.before).equals(StringUtils.defaultString(this.before))
                    && StringUtils.defaultString(that.after).equals(StringUtils.defaultString(this.after))
                    && (that.span == this.span);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return new HashCodeBuilder(5, 47).append(this.row).append(this.column)
                .append(StringUtils.defaultString(this.before)).append(StringUtils.defaultString(this.after))
                .toHashCode();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "@" + this.row + "," + this.column + ": << [" + this.before + "] >> [" + this.after + "]";
    }
}