001/*
002 * ====================================================================
003 *
004 * The Apache Software License, Version 1.1
005 *
006 * Copyright (c) 1999-2003 The Apache Software Foundation.
007 * All rights reserved.
008 *
009 * Redistribution and use in source and binary forms, with or without
010 * modification, are permitted provided that the following conditions
011 * are met:
012 *
013 * 1. Redistributions of source code must retain the above copyright
014 *    notice, this list of conditions and the following disclaimer.
015 *
016 * 2. Redistributions in binary form must reproduce the above copyright
017 *    notice, this list of conditions and the following disclaimer in
018 *    the documentation and/or other materials provided with the
019 *    distribution.
020 *
021 * 3. The end-user documentation included with the redistribution, if
022 *    any, must include the following acknowledgement:
023 *       "This product includes software developed by the
024 *        Apache Software Foundation (http://www.apache.org/)."
025 *    Alternately, this acknowledgement may appear in the software itself,
026 *    if and wherever such third-party acknowledgements normally appear.
027 *
028 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
029 *    Foundation" must not be used to endorse or promote products derived
030 *    from this software without prior written permission. For written
031 *    permission, please contact apache@apache.org.
032 *
033 * 5. Products derived from this software may not be called "Apache"
034 *    nor may "Apache" appear in their names without prior written
035 *    permission of the Apache Software Foundation.
036 *
037 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
038 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
039 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
040 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
041 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
042 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
043 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
044 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
045 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
046 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
047 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
048 * SUCH DAMAGE.
049 * ====================================================================
050 *
051 * This software consists of voluntary contributions made by many
052 * individuals on behalf of the Apache Software Foundation.  For more
053 * information on the Apache Software Foundation, please see
054 * <http://www.apache.org/>.
055 *
056 */
057
058package org.apache.wicket.util.diff.myers;
059
060/**
061 * A node in a diffpath.
062 * 
063 * @version $Revision: 1.1 $ $Date: 2006/03/12 00:24:21 $
064 * @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
065 * 
066 * @see DiffNode
067 * @see Snake
068 * 
069 */
070public abstract class PathNode
071{
072        /** Position in the original sequence. */
073        public final int i;
074        /** Position in the revised sequence. */
075        public final int j;
076        /** The previous node in the path. */
077        public final PathNode prev;
078
079        /**
080         * Concatenates a new path node with an existing diffpath.
081         * 
082         * @param i
083         *            The position in the original sequence for the new node.
084         * @param j
085         *            The position in the revised sequence for the new node.
086         * @param prev
087         *            The previous node in the path.
088         */
089        public PathNode(final int i, final int j, final PathNode prev)
090        {
091                this.i = i;
092                this.j = j;
093                this.prev = prev;
094        }
095
096        /**
097         * Is this node a {@link Snake Snake node}?
098         * 
099         * @return true if this is a {@link Snake Snake node}
100         */
101        public abstract boolean isSnake();
102
103        /**
104         * Is this a bootstrap node?
105         * <p>
106         * In bootstrap nodes one of the two coordinates is less than zero.
107         * 
108         * @return true if this is a bootstrap node.
109         */
110        public boolean isBootstrap()
111        {
112                return (i < 0) || (j < 0);
113        }
114
115        /**
116         * Skips sequences of {@link DiffNode DiffNodes} until a {@link Snake} or bootstrap node is
117         * found, or the end of the path is reached.
118         * 
119         * @return The next first {@link Snake} or bootstrap node in the path, or <code>null</code> if
120         *         none found.
121         */
122        public final PathNode previousSnake()
123        {
124                if (isBootstrap())
125                {
126                        return null;
127                }
128                if (!isSnake() && (prev != null))
129                {
130                        return prev.previousSnake();
131                }
132                return this;
133        }
134
135        /**
136         * {@inheritDoc}
137         */
138        @Override
139        public String toString()
140        {
141                StringBuilder buf = new StringBuilder("[");
142                PathNode node = this;
143                while (node != null)
144                {
145                        buf.append("(");
146                        buf.append(Integer.toString(node.i));
147                        buf.append(",");
148                        buf.append(Integer.toString(node.j));
149                        buf.append(")");
150                        node = node.prev;
151                }
152                buf.append("]");
153                return buf.toString();
154        }
155}