/*
* 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 com.xpn.xwiki.doc.rcs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.suigeneris.jrcs.util.ToString;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
/**
* Contains differences between revisions. One field (diff for xml or full xml) for now. Created for easy migration to
* future XWikiPatch system.
*
* @version $Id: 20be04bcd1aec6b754c7611f4caa9daf1e79882e $
* @since 1.2M1
*/
public class XWikiPatch
{
/** Logger. */
private static final Logger LOGGER = LoggerFactory.getLogger(XWikiPatch.class);
/** string serialization for patch. */
private String content;
/** is content a difference, or full version. */
private boolean isDiff;
/** Default constructor, need for hibernate. */
public XWikiPatch()
{
}
/**
* @param content - patch content
* @param isDiff - is patch a difference or full version
*/
public XWikiPatch(String content, boolean isDiff)
{
setContent(content);
setDiff(isDiff);
}
/**
* @return string serialization for patch
*/
public String getContent()
{
return this.content;
}
/**
* @param content - string serialization for patch
*/
public void setContent(String content)
{
this.content = content;
}
/**
* @return is content a difference. using content field to determine.
*/
private boolean isContentDiff()
{
return !this.content.startsWith("<");
}
/**
* @return is content a difference, or full version
*/
public boolean isDiff()
{
if (this.content != null) {
if (this.isDiff != isContentDiff()) {
LOGGER.warn("isDiff: Patch is inconsistent. Content and diff field are contradicting");
return isContentDiff();
}
}
return this.isDiff;
}
/**
* @param isDiff - is content a difference, or full version
*/
public void setDiff(boolean isDiff)
{
if (this.content != null) {
if (isDiff != isContentDiff()) {
LOGGER.warn("setDiff: Patch is inconsistent. Content and diff field are contradicting");
this.isDiff = isContentDiff();
return;
}
}
this.isDiff = isDiff;
}
/**
* Store the XML export of the document as the history patch; this will be a history milestone.
*
* @param version Document version to store in the history patch.
* @param context Needed for serializing documents to xml.
* @return Self, with the patch content set to the XML export of the document version.
* @throws XWikiException if any error
*/
public XWikiPatch setFullVersion(XWikiDocument version, XWikiContext context)
throws XWikiException
{
return setFullVersion(version.toXML(context));
}
/**
* Store the XML export of the document as the history patch; this will be a history milestone.
*
* @param versionXml Document version to store in the history patch, in the XML export format.
* @return Self, with the patch content set to the XML export of the document version.
* @throws XWikiException if any error occurs
*/
public XWikiPatch setFullVersion(String versionXml) throws XWikiException
{
setContent(versionXml);
setDiff(false);
return this;
}
/**
* Create history patch between originalVersion and newVersion as difference on the XML export of the two versions.
* The patch is created between newVersion and originalVersion.
*
* @param originalVersion Original version of the document document.
* @param newVersion Current version of the document.
* @param context Needed for serializing documents to xml.
* @return Self, with the patch content set to the generated diff between the two version.
* @throws XWikiException if any error occurs
*/
public XWikiPatch setDiffVersion(XWikiDocument originalVersion, XWikiDocument newVersion,
XWikiContext context) throws XWikiException
{
return setDiffVersion(originalVersion.toXML(context), newVersion.toXML(context),
newVersion.getFullName());
}
/**
* Create history patch between originalVersion and newVersion as difference on the XML export of the two versions.
* The patch is created between newVersion and originalVersion.
*
* @param originalVersionXml Original version of the document document, in the XML export format.
* @param newVersion Current version of the document.
* @param context Needed for serializing documents to xml.
* @return Self, with the patch content set to the generated diff between the two version.
* @throws XWikiException if any error occurs
*/
public XWikiPatch setDiffVersion(String originalVersionXml, XWikiDocument newVersion,
XWikiContext context) throws XWikiException
{
return setDiffVersion(originalVersionXml, newVersion.toXML(context), newVersion
.getFullName());
}
/**
* Create history patch between originalVersion and newVersion as difference on the XML export of the two versions.
* The patch is created between newVersion and originalVersion.
*
* @param originalVersionXml Original version of the document document, in the XML export format.
* @param newVersionXml Current version of the document, in the XML export format.
* @param docName Needed for the exception report.
* @return Self, with the patch content set to the generated diff between the two version.
* @throws XWikiException if any error occurs
*/
public XWikiPatch setDiffVersion(String originalVersionXml, String newVersionXml,
String docName) throws XWikiException
{
try {
// The history keeps reversed patches, from the most recent to the previous version.
setContent(XWikiPatchUtils.getDiff(newVersionXml, originalVersionXml));
setDiff(true);
} catch (Exception e) {
Object[] args = { docName };
throw new XWikiException(XWikiException.MODULE_XWIKI_DIFF,
XWikiException.ERROR_XWIKI_DIFF_XML_ERROR,
"Failed to create diff for doc {0}",
e,
args);
}
return this;
}
/**
* Patch text.
*
* @param origText - text to patch
* @throws XWikiException if exception while patching
*/
public void patch(List<String> origText) throws XWikiException
{
if (!isDiff()) {
origText.clear();
origText.addAll(
new ArrayList<String>(Arrays.asList(ToString.stringToArray(getContent()))));
} else {
try {
XWikiPatchUtils.patch(origText, getContent());
} catch (Exception e) {
throw new XWikiException(XWikiException.MODULE_XWIKI_DIFF,
XWikiException.ERROR_XWIKI_DIFF_XML_ERROR,
"Exception while patching",
e);
}
}
}
}