
org.xwiki.rendering.wikimodel.xwiki.xwiki20.XWikiReferenceParser Maven / Gradle / Ivy
/*
* 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.rendering.wikimodel.xwiki.xwiki20;
import org.xwiki.rendering.wikimodel.WikiParameters;
import org.xwiki.rendering.wikimodel.WikiReferenceParser;
/**
* @version $Id: 4e16c533c61978c07df1ae9af11a7f0286cb7267 $
* @since 4.0M1
*/
public class XWikiReferenceParser extends WikiReferenceParser
{
@Override
protected String getLabel(String[] chunks)
{
return chunks[0];
}
@Override
protected String getLink(String[] chunks)
{
return chunks[1];
}
@Override
protected WikiParameters getParameters(String[] chunks)
{
return XWikiWikiParameters.newWikiParameters(chunks[2]);
}
@Override
protected String[] splitToChunks(String str)
{
String[] chunks = new String[3];
char[] array = str.toCharArray();
StringBuffer label = new StringBuffer();
StringBuffer reference = new StringBuffer();
StringBuffer parameters = new StringBuffer();
boolean foundReference = false;
int i = 0;
int nb;
for (boolean escaped = false; i < array.length; ++i) {
char c = array[i];
if (!escaped) {
if (array[i] == '~') {
escaped = true;
} else if ((nb = countFirstChar(array, i, '>')) >= 2) {
for (; nb > 2; --nb) {
label.append(array[i++]);
}
foundReference = true;
i += 2;
parseReference(array, i, reference, parameters);
break;
} else if ((nb = countFirstChar(array, i, '|')) >= 2) {
for (; nb > 2; --nb) {
label.append(array[i++]);
}
i += 2;
parameters.append(array, i, array.length - i);
break;
} else if (c == '[' && i + 1 < array.length
&& array[i + 1] == '[')
{
int endLink = findEndLink(array, i + 2);
if (endLink != -1) {
// If we find an internal link we skip it
label.append(array, i, endLink - i);
i = endLink - 1;
} else {
label.append("[[");
++i;
}
} else {
label.append(c);
}
} else {
label.append(c);
escaped = false;
}
}
if (!foundReference) {
chunks[1] = label.toString();
} else {
chunks[0] = label.toString();
chunks[1] = reference.toString();
}
if (parameters.length() > 0) {
chunks[2] = parameters.toString();
}
return chunks;
}
private int findEndLink(char[] array, int i)
{
int linkdepth = 1;
int endLink = -1;
for (boolean escaped = false; i < array.length; ++i) {
char c = array[i];
if (!escaped) {
if (array[i] == '~') {
escaped = true;
} else if (c == '[' && i + 1 < array.length
&& array[i + 1] == '[')
{
++linkdepth;
++i;
} else if (c == ']' && i + 1 < array.length
&& array[i + 1] == ']')
{
--linkdepth;
++i;
endLink = i + 1;
if (linkdepth == 0) {
break;
}
}
} else {
escaped = false;
}
}
return endLink;
}
/**
* Extract the link and the parameters.
*
* @param array the array to extract information from
* @param i the current position in the array
* @param reference the link buffer to fill
* @param parameters the parameters buffer to fill
*/
private void parseReference(char[] array, int i, StringBuffer reference,
StringBuffer parameters)
{
int nb;
for (boolean escaped = false; i < array.length; ++i) {
char c = array[i];
if (!escaped) {
if (array[i] == '~' && !escaped) {
escaped = true;
} else if ((nb = countFirstChar(array, i, '|')) >= 2) {
for (; nb > 2; --nb) {
reference.append(array[i++]);
}
i += 2;
parameters.append(array, i, array.length - i);
break;
} else {
reference.append(c);
}
} else {
reference.append(c);
escaped = false;
}
}
}
private int countFirstChar(char[] array, int i, char c)
{
int nb = 0;
for (; i < array.length && array[i] == c; ++i) {
++nb;
}
return nb;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy