Added tolerance of optional FTL 1.6.1 root tags when patching
This commit is contained in:
parent
8f8d2072a9
commit
a5383766ef
3 changed files with 101 additions and 40 deletions
|
@ -39,6 +39,12 @@ The Append Extension
|
|||
When you're not overriding something, try to use unique names, so that
|
||||
it won't clobber another mod and vice versa.
|
||||
|
||||
FTL 1.6.1 introduced <FTL>...</FTL> root tags wrapping XML files. If present,
|
||||
Slipstream will remove them, append, and put them back afterward. Special
|
||||
tags (see "Advanced XML" below) will be unaware of them. Mod files are not
|
||||
required to include these root tags, though they can. Slipstream will remove
|
||||
those as well.
|
||||
|
||||
|
||||
General
|
||||
|
||||
|
|
|
@ -35,7 +35,9 @@ import net.vhati.modmanager.core.SloppyXMLParser;
|
|||
|
||||
import ar.com.hjg.pngj.PngReader;
|
||||
|
||||
import org.jdom2.Content;
|
||||
import org.jdom2.Document;
|
||||
import org.jdom2.Element;
|
||||
import org.jdom2.JDOMException;
|
||||
import org.jdom2.input.JDOMParseException;
|
||||
import org.jdom2.input.SAXBuilder;
|
||||
|
@ -166,6 +168,10 @@ public class ModUtilities {
|
|||
* tacked on as-is. Any xml declaration tags will be scrubbed from both
|
||||
* streams, and a new one will be prepended.
|
||||
*
|
||||
* If the mainStream had <FTL> tags (introduced in FTL 1.6.1), they
|
||||
* will be scrubbed, and new ones will be added after appending. If
|
||||
* appendStream has those tags, they will be scrubbed.
|
||||
*
|
||||
* The two InputStreams are read, and the combined result is returned as a
|
||||
* new third InputStream.
|
||||
*
|
||||
|
@ -182,13 +188,27 @@ public class ModUtilities {
|
|||
* the source of new content to append as the first argument).
|
||||
*/
|
||||
public static InputStream appendXMLFile( InputStream mainStream, InputStream appendStream, String encoding, String mainDescription, String appendDescription ) throws IOException {
|
||||
Pattern xmlDeclPtn = Pattern.compile( "<[?]xml [^>]*?[?]>\n*" );
|
||||
// XML declaration, or root FTL tags.
|
||||
Pattern comboPtn = Pattern.compile( "(<[?]xml [^>]*?[?]>\n*)|(</?FTL>)" );
|
||||
Matcher m = null;
|
||||
boolean mainHadRootTags = false;
|
||||
|
||||
String mainText = decodeText( mainStream, mainDescription ).text;
|
||||
mainText = xmlDeclPtn.matcher( mainText ).replaceFirst( "" );
|
||||
StringBuffer mainBuf = new StringBuffer( mainText.length() );
|
||||
m = comboPtn.matcher( mainText );
|
||||
while ( m.find() ) {
|
||||
if ( m.group( 2 ) != null ) mainHadRootTags = true;
|
||||
m.appendReplacement( mainBuf, "" );
|
||||
}
|
||||
m.appendTail( mainBuf );
|
||||
|
||||
String appendText = decodeText( appendStream, appendDescription ).text;
|
||||
appendText = xmlDeclPtn.matcher( appendText ).replaceFirst( "" );
|
||||
StringBuffer appendBuf = new StringBuffer( appendText.length() );
|
||||
m = comboPtn.matcher( appendText );
|
||||
while ( m.find() ) {
|
||||
m.appendReplacement( appendBuf, "" );
|
||||
}
|
||||
m.appendTail( appendBuf );
|
||||
|
||||
// Concatenate, filtering the stream to standardize newlines and encode.
|
||||
//
|
||||
|
@ -197,10 +217,12 @@ public class ModUtilities {
|
|||
Writer writer = new EOLWriter( new OutputStreamWriter( tmpData, encoder ), "\r\n" );
|
||||
|
||||
writer.append( "<?xml version=\"1.0\" encoding=\""+ encoding +"\"?>\n" );
|
||||
writer.append( mainText );
|
||||
if ( mainHadRootTags ) writer.append( "<FTL>\n" );
|
||||
writer.append( mainBuf );
|
||||
writer.append( "\n\n<!-- Appended by Slipstream -->\n\n" );
|
||||
writer.append( appendText );
|
||||
writer.append( appendBuf );
|
||||
writer.append( "\n" );
|
||||
if ( mainHadRootTags ) writer.append( "</FTL>\n" );
|
||||
writer.flush();
|
||||
InputStream result = new ByteArrayInputStream( tmpData.toByteArray() );
|
||||
|
||||
|
@ -211,6 +233,10 @@ public class ModUtilities {
|
|||
/**
|
||||
* Appends and modifies mainStream, using content from appendStream.
|
||||
*
|
||||
* If the mainStream had <FTL> tags (introduced in FTL 1.6.1), they
|
||||
* will be scrubbed, and new ones will be added after appending. If
|
||||
* appendStream has those tags, they will be scrubbed.
|
||||
*
|
||||
* The two InputStreams are read, and the combined result
|
||||
* is returned as a new third InputStream.
|
||||
*
|
||||
|
@ -227,19 +253,43 @@ public class ModUtilities {
|
|||
* @see net.vhati.modmanager.core.SloppyXMLOutputProcessor
|
||||
*/
|
||||
public static InputStream patchXMLFile( InputStream mainStream, InputStream appendStream, String encoding, boolean globalPanic, String mainDescription, String appendDescription ) throws IOException, JDOMException {
|
||||
Pattern xmlDeclPtn = Pattern.compile( "<[?]xml [^>]*?[?]>\n*" );
|
||||
// XML declaration, or root FTL tags.
|
||||
Pattern comboPtn = Pattern.compile( "(<[?]xml [^>]*?[?]>\n*)|(</?FTL>)" );
|
||||
Matcher m = null;
|
||||
boolean mainHadRootTags = false;
|
||||
String wrapperOpenTag = "<wrapper xmlns:mod='mod' xmlns:mod-append='mod-append' xmlns:mod-overwrite='mod-overwrite'>";
|
||||
String wrapperCloseTag = "</wrapper>";
|
||||
StringBuffer buf = null;
|
||||
|
||||
String mainText = decodeText( mainStream, mainDescription ).text;
|
||||
mainText = xmlDeclPtn.matcher( mainText ).replaceFirst( "" );
|
||||
mainText = "<wrapper xmlns:mod='mod' xmlns:mod-append='mod-append' xmlns:mod-overwrite='mod-overwrite'>"+ mainText +"</wrapper>";
|
||||
Document mainDoc = parseStrictOrSloppyXML( mainText, mainDescription+" (wrapped)" );
|
||||
buf = new StringBuffer( wrapperOpenTag.length() + mainText.length() + wrapperCloseTag.length() );
|
||||
buf.append( wrapperOpenTag );
|
||||
m = comboPtn.matcher( mainText );
|
||||
while ( m.find() ) {
|
||||
if ( m.group( 2 ) != null ) mainHadRootTags = true;
|
||||
m.appendReplacement( buf, "" );
|
||||
}
|
||||
m.appendTail( buf );
|
||||
buf.append( wrapperCloseTag );
|
||||
mainText = null;
|
||||
Document mainDoc = parseStrictOrSloppyXML( buf, mainDescription+" (wrapped)" );
|
||||
buf.setLength( 0 );
|
||||
|
||||
String appendText = decodeText( appendStream, appendDescription ).text;
|
||||
appendText = xmlDeclPtn.matcher( appendText ).replaceFirst( "" );
|
||||
appendText = "<wrapper xmlns:mod='mod' xmlns:mod-append='mod-append' xmlns:mod-overwrite='mod-overwrite'>"+ appendText +"</wrapper>";
|
||||
Document appendDoc = parseStrictOrSloppyXML( appendText, appendDescription+" (wrapped)" );
|
||||
buf.ensureCapacity( wrapperOpenTag.length() + appendText.length() + wrapperCloseTag.length() );
|
||||
buf.append( wrapperOpenTag );
|
||||
m = comboPtn.matcher( appendText );
|
||||
while ( m.find() ) {
|
||||
m.appendReplacement( buf, "" );
|
||||
}
|
||||
m.appendTail( buf );
|
||||
buf.append( wrapperCloseTag );
|
||||
appendText = null;
|
||||
Document appendDoc = parseStrictOrSloppyXML( buf, appendDescription+" (wrapped)" );
|
||||
buf.setLength( 0 );
|
||||
|
||||
buf.trimToSize(); // Free the buffer.
|
||||
buf = null;
|
||||
|
||||
XMLPatcher patcher = new XMLPatcher();
|
||||
patcher.setGlobalPanic( globalPanic );
|
||||
|
@ -247,6 +297,20 @@ public class ModUtilities {
|
|||
mainDoc = null;
|
||||
appendDoc = null;
|
||||
|
||||
// Add FTL tags and move all content inside them.
|
||||
// Collect live getContent() results in an Arraylist to avoid
|
||||
// ConcurrentModificationException when detaching in the loop.
|
||||
if ( mainHadRootTags ) {
|
||||
Element mergedRoot = mergedDoc.getRootElement();
|
||||
Element ftlNode = new Element( "FTL" );
|
||||
List<Content> mergedContentList = new ArrayList<Content>( mergedRoot.getContent() );
|
||||
for ( Content c : mergedContentList ) { //
|
||||
c.detach();
|
||||
}
|
||||
ftlNode.addContent( mergedContentList );
|
||||
mergedRoot.addContent( ftlNode );
|
||||
}
|
||||
|
||||
// Bake XML into text, filtering the stream to standardize newlines and encode.
|
||||
// TODO: sloppyPrint() needs EOL normalizing!?
|
||||
//
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.awt.event.FocusEvent;
|
|||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -63,7 +64,6 @@ import net.vhati.modmanager.core.SloppyXMLOutputProcessor;
|
|||
import net.vhati.modmanager.core.XMLPatcher;
|
||||
import net.vhati.modmanager.ui.ClipboardMenuMouseListener;
|
||||
|
||||
import org.jdom2.Document;
|
||||
import org.jdom2.JDOMException;
|
||||
|
||||
|
||||
|
@ -73,7 +73,7 @@ import org.jdom2.JDOMException;
|
|||
public class ModXMLSandbox extends JFrame implements ActionListener {
|
||||
|
||||
private UndoManager undoManager = new UndoManager();
|
||||
private Document mainDoc = null;
|
||||
private String mainText = null;
|
||||
|
||||
private File datsDir;
|
||||
|
||||
|
@ -344,17 +344,11 @@ public class ModXMLSandbox extends JFrame implements ActionListener {
|
|||
if ( innerPath == null ) return;
|
||||
|
||||
is = pack.getInputStream( innerPath );
|
||||
String mainText = ModUtilities.decodeText( is, pack.getName()+":"+innerPath ).text;
|
||||
InputStream rebuiltStream = ModUtilities.rebuildXMLFile( is, "windows-1252", pack.getName()+":"+innerPath );
|
||||
String rebuiltText = ModUtilities.decodeText( rebuiltStream, "Sandbox Main XML" ).text;
|
||||
is.close();
|
||||
|
||||
mainText = mainText.replaceFirst( "<[?]xml [^>]*?[?]>", "" );
|
||||
mainText = "<wrapper xmlns:mod='mod' xmlns:mod-append='mod-append' xmlns:mod-overwrite='mod-overwrite'>"+ mainText +"</wrapper>";
|
||||
mainDoc = ModUtilities.parseStrictOrSloppyXML( mainText, "Sandbox Main XML" );
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
SloppyXMLOutputProcessor.sloppyPrint( mainDoc, writer, null );
|
||||
String displayedText = writer.toString().replaceAll( "\r(?!\n)|(?<!\r)\n|\r\n", "\n" ); // sloppyPrint needs normalizing!?
|
||||
mainArea.setText( displayedText );
|
||||
mainArea.setText( rebuiltText );
|
||||
mainArea.setCaretPosition( 0 );
|
||||
areasPane.setSelectedComponent( mainScroll );
|
||||
resultArea.setText( "" );
|
||||
|
@ -378,29 +372,26 @@ public class ModXMLSandbox extends JFrame implements ActionListener {
|
|||
|
||||
|
||||
private void patch() {
|
||||
if ( mainDoc == null ) return;
|
||||
String mainText = mainArea.getText();
|
||||
if ( mainText.length() == 0 ) return;
|
||||
|
||||
messageArea.setText( "" );
|
||||
|
||||
try {
|
||||
InputStream mainStream = new ByteArrayInputStream( mainText.getBytes( "UTF-8" ) );
|
||||
|
||||
String appendText = appendArea.getText();
|
||||
appendText = appendText.replaceFirst( "<[?]xml [^>]*?[?]>", "" );
|
||||
appendText = "<wrapper xmlns:mod='mod' xmlns:mod-append='mod-append' xmlns:mod-overwrite='mod-overwrite'>"+ appendText +"</wrapper>";
|
||||
Document appendDoc = ModUtilities.parseStrictOrSloppyXML( appendText, "Sandbox Append XML" );
|
||||
InputStream appendStream = new ByteArrayInputStream( appendText.getBytes( "UTF-8" ) );
|
||||
|
||||
XMLPatcher patcher = new XMLPatcher();
|
||||
patcher.setGlobalPanic( false );
|
||||
Document resultDoc = patcher.patch( mainDoc, appendDoc );
|
||||
InputStream resultStream = ModUtilities.patchXMLFile( mainStream, appendStream, "windows-1252", false, "Sandbox Main XML", "Sandbox Append XML" );
|
||||
String resultText = ModUtilities.decodeText( resultStream, "Sandbox Result XML" ).text;
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
SloppyXMLOutputProcessor.sloppyPrint( resultDoc, writer, null );
|
||||
String displayedText = writer.toString().replaceAll( "\r(?!\n)|(?<!\r)\n|\r\n", "\n" ); // sloppyPrint needs normalizing!?
|
||||
resultArea.setText( displayedText );
|
||||
resultArea.setText( resultText );
|
||||
resultArea.setCaretPosition( 0 );
|
||||
areasPane.setSelectedComponent( resultScroll );
|
||||
}
|
||||
catch ( Exception f ) {
|
||||
messageArea.setText( f.getMessage() );
|
||||
catch ( Exception e ) {
|
||||
messageArea.setText( e.toString() );
|
||||
messageArea.setCaretPosition( 0 );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue